MySQL unifying columns - mysql

I have a table that looks something like the following:
id
id_player1
id_player2
1
2
1
2
3
2
I would like to know if there is a way to make it something like:
id
player_selected
opponent
1
2
1
2
2
3
I have got my basic MySQL query:
SELECT * FROM `pairings`
WHERE id = $id AND id_player1 = $idPlayer OR id_player2 = $idPlayer
I'm not used to make much queries for mysql, and I don't much about them and if this is possible.

I'd do it this way:
SELECT id, id_player1 AS player_selected, id_player2 AS opponent
FROM pairings
WHERE id_player1 = $idPlayer
UNION
SELECT id, id_player2, id_player1
FROM pairings
WHERE id_player2 = $idPlayer;
This has an advantage that it makes use of indexes on both id_player1 and id_player2.
(Defining column aliases with AS is not needed on the second SELECT because the aliases defined in the first SELECT take priority anyway.)

I can to advice next query:
select
id,
if (id_player1 = $idPlayer, id_player1, id_player2) as player_selected,
if (id_player1 <> $idPlayer, id_player1, id_player2) as opponent
from pairings
where id_player1 = $idPlayer or id_player2 = $idPlayer
;
This query also can use index based on two fields (id_player1, id_player2)
Here live SQL

Related

Having multiple statements on where clause with same column name

I have a sample SQL statement that says:
SELECT * from users WHERE id = 2 OR id = 5 OR id = 7
What I would like is to avoid repeating id each time in the where clause. Is there a shortcut for this in MySQL that will allow me to mention the id only once?
Yes, the IN clause
SELECT * from users WHERE id IN(2,5,7);
if these Ids you are using in the comparison come from another table you can even do
SELECT * FROM users WHERE id in (SELECT other_id FROM other_table WHERE somecondition)
e4c5 gave you the answer you needed, but here is something else you can do with IN:
select * from users where 'steve' IN (users.fname, users.lname)

Select 2 different columns from 2 different tables

I'm trying to select 2 different columns (newsID from the table news and movID from the table movies) so that I can use mysql_num_rows to grab the items in those conditions.
I tried this with the code below, but it is not working. How can I fix it?
$queryy="SELECT newsID FROM ".PREFIX."news WHERE published='1'";
$queryy="UNION (SELECT movID FROM ".PREFIX."movies WHERE activated='2')";
$all=safe_query($queryy);
$gesamt=mysql_num_rows($all);
You're overwriting the variable with the second assignment. Do it all in one string assignment:
$queryy = "SELECT newsID FROM ".PREFIX."news WHERE published='1'
UNION (SELECT movID FROM ".PREFIX."movies WHERE activated='2')";

In SQL if where condition does not yield result fetch other rows

I have Query like this
Select * from customers where id = 123 and name like '%tester%';
If id : 123 and name : "tester" doesn’t exist in table i should fetch other rows with name "tester" discarding condition "id". if it exists fetch row for that id and name.
Guys i know this is can be handled in program, i want this to be done in my Query, can you please STOP DOWN VOTING and give me the solution if you know!!!
You can try something like this:
SELECT *
FROM CUSTOMERS
WHERE ( ID = 123
AND NAME LIKE '%tester%' )
OR ( NAME LIKE '%tester%'
AND NOT EXISTS (SELECT *
FROM CUSTOMERS
WHERE ID = 123
AND NAME LIKE '%tester%') )
You can find a working example on SQL Fiddle.
SELECT * FROM customers WHERE (id = 123 AND name like '%tester%') OR (name LIKE '%tester%') LIMIT 1;
It should work then
I gotcha here, check it
Select * from customers where id = 3 or name like '%tester%'
order by id=3 desc limit 1;
See you will get all rows that have either id= 3 or name is like tester. From there you will order then by the boolean value (1 if true) by if they == 3. Limiting this to 1 result will get you only the best response.
Likewise if you want to get all results you could remove the limit, assume the top one is the best result. If the first results id is not = 3 then you could say that all the results are just best matches.

Get a list of ids not present in a table

I have a list of ids, and I want to query a mysql table for ids not present in the table.
e.g.
list_of_ids = [1,2,4]
mysql table
id
1
3
5
6
..
Query should return [2,4] because those are the ids not in the table
since we cant view ur code i can only work on asumption
Try this anyway
SELECT id FROM list_of_ids
WHERE id NOT IN (SELECT id
FROM table)
I hope this helps
There is a horrible text-based hack:
SELECT
substr(result,2,length(result)-2) AS notmatched
FROM (
SELECT
#set:=replace(#set,concat(',',id,','),',') AS result
FROM (
select #set:=concat(',',
'1,2,4' -- your list here
,',')
) AS setinit,
tablename --Your tablename here
) AS innerview
ORDER BY LENGTH(result)
LIMIT 1;
If you represent your ids as a derived table, then you can do this directly in SQL:
select list.val
from (select 1 as val union all
select 2 union all
select 4
) list left outer join
t
on t.id = list.val
where t.id is null;
SQL doesn't really have a "list" type, so your question is ambiguous. If you mean a comma separated string, then a text hack might work. If you mean a table, then something like this might work. If you are constructing the SQL statement, I would advise you to go down this route, because it should be more efficient.

How to find the next record after a specified one in SQL?

I'd like to use a single SQL query (in MySQL) to find the record which comes after one that I specify.
I.e., if the table has:
id, fruit
-- -----
1 apples
2 pears
3 oranges
I'd like to be able to do a query like:
SELECT * FROM table where previous_record has id=1 order by id;
(clearly that's not real SQL syntax, I'm just using pseudo-SQL to illustrate what I'm trying to achieve)
which would return:
2, pears
My current solution is just to fetch all the records, and look through them in PHP, but that's slower than I'd like. Is there a quicker way to do it?
I'd be happy with something that returned two rows -- i.e. the one with the specified value and the following row.
EDIT: Sorry, my question was badly worded. Unfortunately, my definition of "next" is not based on ID, but on alphabetical order of fruit name. Hence, my example above is wrong, and should return oranges, as it comes alphabetically next after apples. Is there a way to do the comparison on strings instead of ids?
After the question's edit and the simplification below, we can change it to
SELECT id FROM table WHERE fruit > 'apples' ORDER BY fruit LIMIT 1
SELECT * FROM table WHERE id > 1 ORDER BY id LIMIT 1
Even simpler
UPDATE:
SELECT * FROM table WHERE fruit > 'apples' ORDER BY fruit LIMIT 1
So simple, and no gymnastics required
Select * from Table
where id =
(Select Max(id) from Table
where id < #Id)
or, based on the string #fruitName = 'apples', or 'oranges' etc...
Select * from Table
where id =
(Select Max(id) from Table
where id < (Select id from Table
Where fruit = #fruitName))
I'm not familiar with the MySQL syntax, but with SQL Server you can do something with "top", for example:
SELECT TOP 1 * FROM table WHERE id > 1 ORDER BY id;
This assumes that the id field is unique. If it is not unique (say, a foreign key), you can do something similar and then join back against the same table.
Since I don't use MySQL, I am not sure of the syntax, but would imagine it to be similar.
Unless you specify a sort order, I don't believe the concepts of "previous" or "next" are available to you in SQL. You aren't guaranteed a particular order by the RDBMS by default. If you can sort by some column into ascending or descending order that's another matter.
This should work. The string 'apples' will need to be a parameter.
Fill in that parameter with a string, and this query will return the entire record for the first fruit after that item, in alphabetical order.
Unlike the LIMIT 1 approach, this should be platform-independent.
--STEP THREE: Get the full record w/the ID we found in step 2
select *
from
fruits fr
,(
--STEP TWO: Get the ID # of the name we found in step 1
select
min(vendor_id) min_id
from
fruits fr1
,(
--STEP ONE: Get the next name after "apples"
select min(name) next_name
from fruits frx
where frx.name > 'apples'
) minval
where fr1.name = minval.next_name
) x
where fr.vendor_id = x.min_id;
The equivalent to the LIMIT 1 approach in Oracle (just for reference) would be this:
select *
from
(
select *
from fruits frx
where frx.name > 'apples'
order by name
)
where rownum = 1
I don't know MySQL SQL but I still try
select n.id
from fruit n
, fruit p
where n.id = p.id + 1;
edit:
select n.id, n.fruitname
from fruits n
, fruits p
where n.id = p.id + 1;
edit two:
Jason Lepack has said that that doesn't work when there are gaps and that is true and I should read the question better.
I should have used analytics to sort the results on fruitname
select id
, fruitname
, lead(id) over (order by fruitname) id_next
, lead(fruitname) over (order by fruitname) fruitname_next
from fruits;
If you are using MS SQL Server 2008 (not sure if available for previous versions)...
In the event that you are trying to find the next record and you do not have a unique ID to reference in an applicable manner, try using ROW_NUMBER(). See this link
Depending on how savvy your T-SQL skill is, you can create row numbers based on your sorting order. Then you can find more than just the previous and next record. Utilize it in views or sub-queries to find another record relative to the current record's row number.
SELECT cur.id as id, nxt.id as nextId, prev.id as prevId FROM video as cur
LEFT JOIN video as nxt ON nxt.id > cur.id
LEFT JOIN video as prev ON prev.id < cur.id
WHERE cur.id = 12
ORDER BY prev.id DESC, nxt.id ASC
LIMIT 1
If you want the item with previous and next item this query lets you do just that.
This also allows You to have gaps in the data!
How about this:
Select * from table where id = 1 + 1