Combine two SELECT queries together by using value from SELECT in WHERE - mysql

id | number
---|--------
1 | null
2 | 1
3 | null
4 | 0
5 | 4
6 | 4
This is what I want to do this in one query. How can I combine both of these queries together?
$id = 4;
SELECT * FROM users WHERE id = $id OR number = $id
// This will return rows 4,5,6
2nd query:
$id = 5;
SELECT * FROM users WHERE id = $id AND id = $numberColumnOfId AND number = $numberOfColumnId;
// This will return rows 4,5,6
$numberColumnOfId is the number of the $id. So if the $id = 5, then the number would be 4. So select rows where ID = 5.
How can I combine both of the SELECT statements together?

Use two queries that you combine with UNION.
The first query gets the rows with the given $id, the second query gets the ones that match via thenumber` column.
SELECT *
FROM users
WHERE id = $id OR number = $id
UNION
SELECT u1.*
FROM users AS u1
JOIN users AS u2 ON u1.number = u2.number OR u1.id = u2.number
WHERE u2.id = $id or u2.number = $id
DEMO

Related

SELECT where with multiple conditions in ONE query

There are two things I want to achieve.
This is my database table called "table".
id | friend
---|--------
1 | null
2 | 1
3 | 0
4 | 3
5 | 3
6 | null
There are two SELECT queries I want to do.
$id = 3;
SELECT * FROM table WHERE id = $id; // Not sql injection safe, just an example
This should select row id = 3. If that row's friend column = 0, then:
SELECT rows WHERE friend = $id.
If that row's friend column is something other than 0, then just return that row, row 3. But since my table above shows that row id 3's friend column = 0, this should altogether return rows: 3, 4, 5.
Also, another scenario a something a little different:
$id = 5;
SELECT * FROM table WHERE id = $id;
If that row's friend column <> (does NOT equal) 0 AND IS NOT NULL, then use the friend number and:
SELECT * WHERE id = friend from previous table.
In this example, it will return rows 3, 4, 5 because ID = 5 and the friend ID of 5 is 3. So we search columns id AND friend for 3 and we select it.
I want to combine all of those together into one MySQL SELECT query. How can I do that?
Any help will be appreciated!
In the first scenario, I don't understand exactly why a zero value for friend returns 3, 4, and 5. Why not 2? I'm assuming that if the friend value is zero, then add the rows which have you as a friend.
So, before this first example, I cannot stand a table named "table", so I will use friends as the name of the table.
SELECT FF.id
FROM friends FF
INNER JOIN friends FID on FF.friend = FID.id
WHERE FID.friend = 0 AND FID = $id
UNION
SELECT F2.id FROM friends F2 WHERE F2.id = $id AND F2.friend IS NOT NULL
The inner join, takes the id of friends (FID.id) and joins on the the friends table again to get all the records with that as a friend (FF.friend) value.
Then UNION will include the original id. Both sides of the UNION will return no results if the friend field is NULL.
Similarly for the second scenario, use the given value, ($id = 5), find that record's friend value, and query for all records with that as a friend, then union its record.
SELECT FF.id
FROM friends FF
WHERE FF.friend = (SELECT FIN.friend FROM friends FIN where FIN.id = $id)
UNION
SELECT FIN.friend FROM friends FIN where FIN.id = $id

MySQL left join with exists subquery returns more rows than it should

I have a MySQL database and SQL query with subqueries.
I'm 100% sure that the table s_k_p has only one row where s_k_p.season_id = 2 and s_k_p.user_id = k_i.user_id.
Anyway, the problem is that LEFT JOIN s_k_p AS skp2 part returns 10 rows. As said, it should return only one row.
SELECT skp2.season_id AS invalid_status_id
FROM comp_i
INNER JOIN k_i ON k_i.ilmo_id = comp_i.id
LEFT JOIN s_k_p
ON s_k_p.user_id = k_i.user_id
AND s_k_p.season_id = 4
LEFT JOIN s_k_p AS skp2
ON skp2.user_id = k_i.user_id
AND EXISTS (
SELECT *
FROM s_k_p
WHERE s_k_p.season_id = 2
AND s_k_p.user_id = k_i.user_id
)
WHERE comp_i.comp_id = ?
ORDER BY k_i.id ASC
The table s_k_p has the following rows:
season_id | user_id
1 | 25
1 | 459
2 | 459
3 | 459
3 | 9999
4 | 459
4 | 758
The second row is the only one where s_k_p.season_id = 2 and s_k_p.user_id = k_i.user_id should be true.
your query probably is correct in returning 10 rows if there are 10 rows for the USER in the S_K_P table because THAT is the left-join.
You have your exist to a SECONDARY level to the same S_K_P table but INCLUDING the Season_ID = 2.
If what you care about is only if it exists for the same user, season 2, then change to
LEFT JOIN s_k_p AS skp2
ON skp2.user_id = k_i.user_id
AND skp2.season_id = 2

Conditional condition in ON clause

I am trying to apply a conditional condition inside ON clause of a LEFT JOIN. What I am trying to achieve is somewhat like this:
Pseudo Code
SELECT * FROM item AS i
LEFT JOIN sales AS s ON i.sku = s.item_no
AND (some condition)
AND (
IF (s.type = 0 AND s.code = 'me')
ELSEIF (s.type = 1 AND s.code = 'my-group')
ELSEIF (s.type = 2)
)
I want the query to return the row, if it matches any one of the conditions (Edit: and if it matches one, should omit the rest for the same item).
Sample Data
Sales
item_no | type | code | price
1 0 me 10
1 1 my-group 12
1 2 14
2 1 my-group 20
2 2 22
3 2 30
4 0 not-me 40
I want the query to return
item_no | type | code | price
1 0 me 10
2 1 my-group 20
3 2 30
Edit: The sales is table is used to apply special prices for individual users, user groups, and/or all users.
if type = 0, code contains username. (for a single user)
if type = 1, code contains user-group. (for users in a group)
if type = 2, code contains empty-string (for all users).
Use the following SQL (assumed, the the table sales has a unique id field as usual in yii):
SELECT * FROM item AS i
LEFT JOIN sales AS s ON i.sku = s.item_no
AND id = (
SELECT id FROM sales
WHERE item_no = i.sku
AND (type = 0 AND code = 'me' OR
type = 1 AND code = 'my-group' OR
type = 2)
ORDER BY type
LIMIT 1
)
Try following -
SELECT *,SUBSTRING_INDEX(GROUP_CONCAT(s.type ORDER BY s.type),','1) AS `type`, SUBSTRING_INDEX(GROUP_CONCAT(s.code ORDER BY s.type),','1) AS `code`,SUBSTRING_INDEX(GROUP_CONCAT(s.price ORDER BY s.type),','1) AS `price`
FROM item AS i
LEFT JOIN sales AS s
ON i.sku = s.item_no AND (SOME CONDITION)
GROUP BY i.sku

Select and join on dynamic table name

I would like to get all information about every item. Items has global variable (here on_stock), but every item has also its own property in different table, and that table has the same name as the items type name.
select items
join its type_id on types table id -> name
join selected item on name.id
Here is the sample:
[items]
id | on_stock | type_id
-----+----------+-----------
1 1 1(=car)
2 0 1(=car)
3 1 2(=ship)
4 0 2(=ship)
[types]
id | name
----+--------
1 car
2 ship
[car]
id | top_speed
----+-----------
1 200
2 300
[ship]
id | color
-----+-------
3 red
4 blue
expected result:
1 on_stock=1 top_speed=200
2 on_stock=0 top_speed=300
3 on_stock=1 color=red
4 on_stock=0 color=blue
Please help to achieve this!
If I could not do it in one request, I'll do it in more(1+item types count).
first, I need the required types as array(id=>name):
$req_types = array();
$rs = mysql_query("
SELECT items.type_id,types.name
FROM items
JOIN types ON items.type_id=type.id
GROUP BY items.type_id
");
while($type= mysql_fetch_assoc($rs))
$req_types[$type['id']] = $type['name'];
then I need the common and individual item data:
$groups = array();
foreach($req_types as $table)
{
$rs = mysql_query("
SELECT items.*,$table.*
FROM items
JOIN $table ON $table.id=items.id
");
while($item = mysql_fetch_assoc($rs))
$groups[$table][] = $item;
}
It isn't pretty, but neither is the data structure. Here is a query to do what you want
SELECT I.id, I.On_stock, C.top_speed,S.Color
FROM ITEMS I
LEFT JOIN Car C ON (I.ID = C.CarID)
LEFT JOIN Ship S ON (I.ID = S.ShipID)
You will have to tweak the query every time you add a new item type, but that is just a downside of this data structure.

Does MySQL table row contain two values

I have a table with two columns:
ID1 | ID2
---------
1 | A
3 | V
1 | C
4 | B
5 | Q
1 | S
And I want to be able to find out if any row has, say ID1 = 5 and ID2 = Q , and return a true / false value.
Yes, Of course
SELECT * FROM table where ID1='5' and ID2='Q'
PHP (I am just guessing this backend)
$query = "SELECT * FROM table where ID1='5' and ID2='Q'";
$result = mysql_query($query);
if(mysql_num_rows($result)) { return true; }
else { return false; }
1 means TRUE for mysql
SELECT 1
FROM your_table
WHERE ID1 = 5 AND ID2 = 'Q'
for example this?
SELECT 1
FROM TABLE
WHERE ID1 = 5 AND ID2 = 'Q'
Efficient query for your purpose (faster than other examples):
SELECT 1 FROM table where ID1='5' and ID2='Q' LIMIT 1
PHP sample:
<?php
$query = "SELECT 1 FROM table where ID1='5' and ID2='Q' LIMIT 1";
echo bool(mysql_num_row(mysql_query($query)));
?>