Get specific "version" of a column - sql

I have an app that uses SQLite to store data locally. There may be more than one file storing the data. All the files contain a list of items, but only one of them has the "correct" status for the current user (basically, there is a "user" db in $HOME and a "system-wide" one in /etc).
Usually, both files will contain the same list of items, and only the status column will differ. If, however, either contains items not in both, I want that data as well.
SQLite does not have FULL OUTER JOIN.
A solution I have come up with is this:
SELECT item, group_concat(status) AS status FROM (SELECT item,status FROM items UNION SELECT item,status FROM otherdb.items) GROUP BY item;
And then parsing the comma-separated "status" output to get the "right" status. I would like a pure SQL solution, however.
The values I want for status are:
If any = 1, status = 1
elif any = -1, status = -1
elif any = 2, status = 2
elif any = -2, status = -2
else status = 0 or NULL
status may only (in the db) be -2,-1,0,NULL,1,2 so this covers all data.
If there is a solution that only gives whichever one is non-zero and non-null, that could work too, although I would prefer the above.

I would sugest you one approach:
1. create a temp table, one adittional column for a flag "otherbd";
2. throw everything from the 2 tables in there;
3. delete the lines you don't want;

Create a status priority table with the following values
status priority
1 5
-1 4
2 3
-2 2
0 1
NULL 0
The concept is to join your two tables against this StatusPriorty table, Group the records and use MAX(Priority) to get your results

Related

Trying to understand simple SQL query with case statement

I am trying to understand this query:
SELECT *
FROM servers
ORDER BY
CASE
WHEN status = "ACTIVE" THEN 1
WHEN status = "INACTIVE" THEN 2
ELSE 3
END
I know this is selecting all rows from the server table and ordering them first with where column status = "ACTIVE" and then where status = "INACTIVE."
What is the syntax THEN 1...THEN 2 ELSE 3 END mean? I know END is to close the case statement, but what are 1, 2, and 3?
Your CASE clause is in the ORDER BY section - it doesn't become part of the output, it's just used by the SQL engine for sorting.
The 1,2,3 are sortable values.
Basically it' saying to put the ACTIVE rows first (1), then the INACTIVE rows (2), then any rows that are neither (3) at the end.
Given that ACTIVE and INACTIVE sort the same way, I guess there are other values in the table that don't sort in that order (maybe CLOSED or DORMANT which would come before INACTIVE

Ignore a column in MS ACCESS query if the WHERE clause is not set

Problem
I've got a dropdown list, which shows all the Article_Group_ID's that are linked to a specific brand, using the following Query:
SELECT TbArticle.Article_Group_ID, TbArticle.Article_Brand_ID
FROM TbArticle
GROUP BY TbArticle.Article_Group_ID, TbArticle.Article_Brand_ID,
HAVING (((TbArticle.Article_Brand_ID)=1))
This works as expected, it returns the following:
Query results
Article_Brand_ID
Article_Group_ID
1
1
1
2
But, if a user does not wish to specify a specific Article_Brand_ID, the query results look like this:
Query
Article_Brand_ID
Article_Group_ID
1
1
2
1
3
1
1
2
As you can see, the same Article_Group_ID is returned three times. Because of this, the user now sees the same group three times, instead of just once. If I were to remove the Article_Brand_ID from the query, the results would look like this:
Article_Group_ID
1
2
Is there any way to achieve the same behavior, by "ignoring" the Article_Brand_ID column, if it's WHERE clause is not set?
Database layout
TbArticle
Article_Brand_ID
Article_Group_ID
1
1
2
1
3
1
1
2
A single query cannot return a variable number of columns. So, strictly speaking you cannot do what you want with a single query. However, if you are willing to accept the second column as NULL when the brand is not provided, then you can adjust the aggregation.
Let me denote the parameter by ?:
SELECT a.Article_Group_ID,
IIF(? IS NOT NULL, a.Article_Brand_ID, NULL) as Article_Brand_ID
FROM TbArticle as a
WHERE a.Article_Brand_ID = ? OR
? IS NULL
GROUP BY a.Article_Group_ID,
IIF(? IS NOT NULL, a.Article_Brand_ID, NULL);
Note: It is usually better to filter before aggregating (i.e. using WHERE) rather than filtering afterwards (i.e. using HAVING).

How can I update a dynamic amount of records in one SQL query?

An update query like:
UPDATE test
SET x = (case when id = 1 then 99
when id = 2 then 98
end),
y = (case when id = 1 then 42
when id = 2 then 41
end)
will update multiple records where the x and y attributes have different values for each record. But what if the number of records I need to update is dynamic? For simplicity, assume I have an array of id values. I want to update all the records that have an id in that array, and in one query. How could you do that?
It seems like you're already going about this the hard way. Your code is best accomplished with multiple queries:
UPDATE test
SET x = 99, y=42
WHERE id=1;
UPDATE test
SET x = 98, y=41
WHERE id=2;
As for updating "all the records" (as you say), that's a harder question to answer, as it's not clear where the data are coming from. That sort of thing might be best handled with a scripting language. You may have other options. depending on which database platform you're using, but you didn't specify that either.

Updating columns based on a combine rows value on the same table

Please assist if possible, I have used Stuff to combine rows into a single row based on other columns. However I want to turn each of the unique items into it's own column with a number showing if it exists, e.g. 1 or 0 and then doing the same for all subsequent rows?
I have been able to create the columns but I can't get them to update per whats in the one column.
But I want it to be dynamic so matter how many different names appear in categories it creates a new column and adds 1 or 0 if it appears or not
How about something like this for SQL Server?
strSQL = "SELECT Category, CASE WHEN Category IS NOT NULL THEN 1 ELSE 0 END AS IsCategoryExist FROM MyTable"
Sample data (the 2nd column shows as 1 if the first column is non-blank):
Cars, 1
[Blank], 0
Airplanes, 1
Radios, 1

SQL : Check if result = number for each id

I have this sort of structure
ID STATUS
1 FIRSTSTAT
2 FIRSTSTAT
3 FIRSTSTAT
1 SECSTAT
3 SECSTAT
3 THIRDSTAT
3 FOURTHSTAT
3 FIFTHSTAT
I want to get the 3 back because he has all following status (FIRSTSTAT, SECSTAT, THIRDSTAT). Do you have an idea how I could make that?
It should be done by explicitely giving the statuses because other statuses exist so SELECT FROM WHERE = 'THIRDSTAT' is not ok since it should have all three statuses, not only one of them.
So I guess it should be done calculating the SUM or something like that.
I tried the following but of course, it does not work :
SELECT
FROM
WHERE
AND
AND
If the number of different status values is known to always be 3:
select id
from tablename
where status in ('FIRSTSTAT', 'SECSTAT', 'THIRDSTAT')
group by id
having count(distinct status) = 3