Is it possible to run CASE WHEN with pre queried data - mysql

I was wondering if it is possible to get the count of a query, plus check if a entity within the query exists at the same time.
So I was looking to do something like this
SELECT
COUNT(a.*)
CASE WHEN ? IN (a.column) THEN 1 ELSE 0 END AS exist
FROM a
WHERE ...
I know I could do a sub-query in the CASE, but is it possible to do it with just the data from the initial query?
EDIT
ie
+------------+
| id column |
+------------+
| 1 5 |
| 2 6 |
| 3 7 |
| 4 8 |
SELECT
COUNT(a.*)
CASE WHEN 7 IN (a.column) THEN 1 ELSE 0 END AS exist
FROM a
WHERE id > 1
Would return
+--------------------+
| COUNT(*) exist |
+--------------------+
| 3 1 |
Because there are 3 entries with an id > 1 and within the entries and there is an entry with column = 7

If you want to check if a value exists in the column, you can do:
SELECT COUNT(*),
MAX(? = a.column) as value_exists
FROM a
WHERE ...
In a numeric context, MySQL treats booleans as integers, with 1 for true and 0 for false. Hence, this returns true if the value is in any row in the column. You can use MIN() if you want to check if the same value is in all the rows.

Related

Select different column in a row depending on the value

I am trying to return a friend list for my users and I'm trying to gather the value matching their user_id.
| ID | user1_id | user1_status | user2_id | user2_status |
| 1 | 1 | 0 | 2 | 0 |
| 2 | 4 | 1 | 5 | 1 |
| 3 | 4 | 1 | 6 | 0 |
| 4 | 1 | 0 | 4 | 1 |
Here is the problem I have, the value I'm look for can be in either "user1_id"/"user2_id" and then I need to return the "user_status" ONLY for the other user. n. I made this table really simple. In my version there is a lot more columns I want my server to avoid returning.
Let's say that the client user_id is 4, so I need the select all the row with user1_id/user2_id equal to 4 and return the other person user_status. In the table, the first case of the value equal to 4 is in user1_id, I need that row to return the user2_id and user2_status.
Here is what I have so far, but it doesn't work:
SELECT `id`
CASE
WHEN `user1_id`='4' THEN `user2_id` AND `user2_status`
WHEN `user2_id`='4' THEN `user1_id` AND `user1_status`
ELSE NULL
END
from 'relationship'
where `user1_id`='4' OR `user2_id`='4'
How do I write this query statement?
If you refer to the CASE syntax you will see that it's defined to return a single column and not a tuple. Additionally, in your query you are trying to get either (user2_id, user_status) or NULL. Here you get a mismatch in the number of columns which is not allowed either.
If you really really want to use CASE you could do:
SELECT `id`
CASE
WHEN `user1_id`='4' THEN `user2_id`,
ELSE NULL
END
CASE
WHEN `user2_id`='4' THEN `user1_id`
ELSE NULL
END
CASE
WHEN `user1_id`='4' THEN `user1_status`
ELSE NULL
END
CASE
WHEN `user2_id`='4' THEN `user2_status`
ELSE NULL
END
FROM 'relationship'
where `user1_id`='4' OR `user2_id`='4'
yes, clunky and confusing. Much Simpler if you use UNION.
SELECT id, user2_id AS uid, user2_status as ustatus FROM relationship WHERE user1_id = 4
UNION
SELECT id, user1_id AS uid, user1_status as ustatus FROM relationship WHERE user2_id = 4

Mysql query where value is more than a specific entity value

TableA:
------
id | property|
--------------
1 | 0 |
2 | 5 |
3 | 6 |
Is it possible to query in mysql in single command to figure out which has a property value more than that where id=2?
Use a subquery to get the property value for id=2, and compare to that. The subquery must return just one row, which is the case here.
SELECT *
FROM TableA
WHERE property > (SELECT property FROM TableA WHERE id = 2)

Difference between 2 selects in SQL

I have one data table:
--------------------
ID | user | Value
--------------------
1 | 1 | 1
--------------------
2 | 1 | 2
--------------------
3 | 2 | 3
--------------------
4 | 2 | 2
--------------------
5 | 3 | 4
--------------------
6 | 3 | 2
--------------------
I would like to SELECT all rows where value is different comparing to user 1 so the result would be rows with IDs 3 (value is 3) and 5 (value is 2)
I would do something like this (will call it A)
SELECT * FROM table WHERE user = 1
and get all the rows from user 1. Than I would select (will call it B)
SELECT * FROM table WHERE user != 1
and get all other rows. And than I would compare them WHERE A.value != B.value.
I'm stuck on how to merge everything together...
Please help!
Try this:
SELECT *
FROM table
WHERE value NOT IN ( SELECT value FROM table WHERE user = 1)
The relational operator is indeed 'difference', Oracle has the keyword MINUS, Standard SQL has the keyword EXCEPT e.g.
SELECT value
FROM table
EXCEPT
SELECT value
FROM table
WHERE user = 1;
Sadly, MySQL doesn't have any such an operator, you have to use other SQL constructs e.g. NOT IN <table expression>:
SELECT value
FROM table
WHERE value NOT IN ( SELECT value
FROM table
WHERE user = 1 );
select * from table where value not in (select value from table where user = 1);

Find & Sort By Column Name in MYSQL Given Condition

In a table I have the following value:
ID | Exercise1 | Exercise2 | Exercise3
1 | 0 | 0 | 0
2 | 0 | 0 | 0
When a user completes an exercise, the db switches from '0' to '1'. I'm looking for an sql query that searches by the ID number of the user returns the lowest column name that is set to 0.
EX:
ID | Exercise1 | Exercise2 | Exercise3
1 | 1 | 1 | 0
Here the query would return with exercise3, since exercise1 and exercise2 have previously been updated and completed by the user.
I found
SELECT COLUMN_NAME FROM information_schema.columns
but can't put it together with the sorting I'm looking for, any help would be deeply appreciated.
If you have only a handful of exercises (e.g. < 5), then you can simply hardcode the query with a series of nested IF() statements.
If you have more than that, then you should change your data model so each user/exercise mapping is stored in a separate row.
Something like this?
SELECT CASE
WHEN Exercise1=0 THEN 'Exercise1'
WHEN Exercise2=0 THEN 'Exercise2'
WHEN Exercise3=0 THEN 'Exercise3'
ELSE NULL
END AS Exercise
FROM MyTable
WHERE ID = SomeID
Hmmm... you have problems because your design is wrong. The problem is that your database design was affected by how you imagine the presentation of the table. But the database thinking is different. The database would be normally designed this way:
StudentID | ExcerciseID | Completed
1 | 1 | 1
1 | 2 | 1
1 | 3 | 0
2 | 1 | 0
....
And then you can do:
select StudentID, min(ExcerciseID) as FirstExcerciseNotCompleted
from Excercises
where Completed = 0
to see first incomplete excercise for each student, or if you want set next completed excercise to Student 1, just do:
update Excercises
set Completed = 1
where Student = 1 and ExcerciseID = (select min(ExcerciseID) from Excercises where StudentID = 1 and Completed = 0)

MySQL - COUNT before INSERT in one query

Hey all, I am looking for a way to query my database table only once in order to add an item and also to check what last item count was so that i can use the next number.
strSQL = "SELECT * FROM productr"
After that code above, i add a few product values to a record like so:
ID | Product | Price | Description | Qty | DateSold | gcCode
--------------------------------------------------------------------------
5 | The Name 1 | 5.22 | Description 1 | 2 | 09/15/10 | na
6 | The Name 2 | 15.55 | Description 2 | 1 | 09/15/10 | 05648755
7 | The Name 3 | 1.10 | Description 3 | 1 | 09/15/10 | na
8 | The Name 4 | 0.24 | Description 4 | 21 | 09/15/10 | 658140
i need to count how many times it sees gcCode <> 'na' so that i can add a 1 so it will be unique. Currently i do not know how to do this without opening another database inside this one and doing something like this:
strSQL2 = "SELECT COUNT(gcCode) as gcCount FROM productr WHERE gcCode <> 'na'
But like i said above, i do not want to have to open another database query just to get a count.
Any help would be great! Thanks! :o)
There's no need to do everything in one query. If you're using InnoDB as a storage engine, you could wrap your COUNT query and your INSERT command in a single transaction to guarantee atomicity.
In addition, you should probably use NULL instead of na for fields with unknown or missing values.
They're two queries; one is a subset of the other which means getting what you want in a single query will be a hack I don't recommend:
SELECT p.*,
(SELECT COUNT(*)
FROM PRODUCTR
WHERE gccode != 'na') AS gcCount
FROM PRODUCTR p
This will return all the rows, as it did previously. But it will include an additional column, repeating the gcCount value for every row returned. It works, but it's redundant data...