Home > Software design >  Query: How to get data from another row to fill lacking data?
Query: How to get data from another row to fill lacking data?

Time:12-09

(I really struggle with how to ask this question correctly with few words, so sorry for the title. I tried my best.)

I have a database like this:

id animal date no
1 dog blank 0
2 cat blank 0
3 dog 07/12 2021 3
4 dog 08/12 2021 2
5 cat 08/12 2021 4

(The table is a simplified table from a larger project in Android Studio with java.)

I want to query this datebase so that:

  • I get the animals on a certain day
  • If an animal is not given for å certain day, I want the row with that animal and a blank date

Examples:

  • If date is 08/12 2021, I want rows with id 4 and 5.
  • If date is 07/12 2021, I want rows with id 3 and 2 (no cat that day)
  • If date is 06/12 2021 (or any other date), I want rows with id 1 and 2 (no cat nor dog that day)

I know I can get all from a certain date pluss those with blank dates, by:

@Query("SELECT * 
        FROM db 
        WHERE (db.date LIKE :date OR db.date LIKE :blank) 
        ORDER BY no ASC")

But, how can I get what I want instead?

CodePudding user response:

According to your sample data, I think that your datamodel has none right setup.

You will get a problem with this data:

id animal date no
6 cat 09/12 2021 2
7 cat blank 0
8 dog 12/12 2021 3

→ Therefore you must calculate the time-difference between last valid date and previous valid date and have to make differences, when your last date is less then your request date.

e.g. request at 11/11 2021, where your last valid date would be 09/12 2021

It would be better if you set to every INSERT a system-timestamp. Something like this:

id animal date no change_date
6 cat 09/12 2021 2 09/12 2021
7 cat blank 0 10/12 2021
8 dog 12/12 2021 3 12/12 2021

With this setup you have the advantage that you do not have to implicitly assign the ID to possible dates.

With this the result can easily be queried:

SELECT
  *
FROM
  db
WHERE
  db.change_date = '11/12 2021'

UPDATE

If you only want to show a result is available for a certain date:

@Query("SELECT * 
        FROM db 
        WHERE (db.date LIKE :date OR db.date LIKE :blank) AND db.animal = 'cat'
        ORDER BY nr ASC limit 1
        UNION ALL
        SELECT * 
        FROM db 
        WHERE (db.date LIKE :date OR db.date LIKE :blank) AND db.animal = 'dog'
        ORDER BY nr ASC limit 1")

CodePudding user response:

The very quick answer is to just take the first result:

@Query("SELECT * 
        FROM db 
        WHERE (db.date LIKE :date OR db.date LIKE :blank) 
        ORDER BY nr ASC limit 1")
  • Related