SQL query decoding a table with a second look-up table - mysql

I have two tables - Table 1 of ints and Table 2 of strings.
Table 1:
+-------+-------+-------+-------+-------+
| | col A | col B | col C | col D |
+-------+-------+-------+-------+-------+
| row 1 | 1 | | | |
| row 2 | | 2 | | |
| row 3 | 8 | 3 | | |
| row 4 | 9 | | 4 | |
+-------+-------+-------+-------+-------+
Table 2:
+-------+-------+--------------+
| | col A | col B |
+-------+-------+--------------+
| row 1 | 1 | dog |
| row 2 | 2 | cat |
| row 3 | 3 | zebra |
| row 4 | 4 | donkey |
| row 5 | 8 | horse |
| row 6 | 9 | honey badger |
+-------+-------+--------------+
Is there a SQL query that will return the following?
+-------+--------------+-------+--------+-------+
| | col A | col B | col C | col D |
+-------+--------------+-------+--------+-------+
| row 1 | dog | | | |
| row 2 | | cat | | |
| row 3 | horse | zebra | | |
| row 4 | honey badger | | donkey | horse |
+-------+--------------+-------+--------+-------+
At the moment I am SELECT * IN Table_1.
Then querying Table_2 six times to get the result. Is there a more elegent way?
I do want to use SELECT * -- I do not want to specify the table headings in the query (because there are 50+ table headings).

The only way to do lookups for all columns is by mentioning all the columns in the SQL query.
This could be done with one left join for each column, or with correlated subqueries:
SELECT (SELECT colB FROM Table2 WHERE colA = Table1.colA) AS colA,
(SELECT colB FROM Table2 WHERE colA = Table1.colB) AS colB,
(SELECT colB FROM Table2 WHERE colA = Table1.colC) AS colC,
...
FROM Table1
You cannot use SELECT *. If you do not know the columns of Table1, you can read them from the database, and construct the query dynamically.

Related

How to set the value of a row into previous row?

I have a table like this:
// numbers
+----+--------+
| id | numb |
+----+--------+
| 1 | zero |
| 2 | one |
| 3 | two |
| 4 | three |
| 5 | four |
| 6 | five |
| 7 | six |
| 8 | seven |
| 9 | eight |
| 0 | nine |
+----+--------+
Now I'm trying to copy/paste the value of each row (just numb column) to the upper column. So this is expected result:
+----+--------+
| id | numb |
+----+--------+
| 1 | one |
| 2 | two |
| 3 | three |
| 4 | four |
| 5 | five |
| 6 | six |
| 7 | seven |
| 8 | eight |
| 9 | nine |
| 0 | zero |
+----+--------+
Actually I can do that by PHP. I mean I can fetch all rows and shift one itam and then update them. But I want to know can I do that by pure mysql?
All the rows except the max of id will get updated. The max id will still have the same numb. (in this case 9,'eight')
update tablename t1
JOIN tablename t2 on t1.id = t2.id-1
set t1.numb = t2.numb;
Sample Fiddle
Maybe something like
How do I UPDATE from a SELECT in SQL Server?
and use the id+1 for table2.

How to search in multiple columns?

Here is my table:
// table
+----+------+------+
| id | col1 | col2 |
+----+------+------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 3 | 1 |
| 7 | 3 | 2 |
| 8 | 3 | 3 |
| 9 | 3 | 4 |
| 10 | 3 | 5 |
+----+------+------+
Now I want to search in both col1 and col2. Something like this:
select * from table where col1,col2 IN (1,2);
And I want this output:
+----+------+------+
| id | col1 | col2 |
+----+------+------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 3 | 1 |
| 7 | 3 | 2 |
+----+------+------+
Well, My problem is on this part: ... where col1,col2 IN (1,2). How can I solve it?
Note: I can do that like this: ... where col1 IN (1,2) or ,col2 IN (1,2). But this this way, I have to create two separate index on each column. While I want a query which need to a group-index like this: KEY NameIndex (col1, col2)
You want this, correct?
WHERE col1 IN (1,2)
OR col2 IN (1,2)
If so, turn the OR into a UNION. (This is a common optimization trick.)
( SELECT ... WHERE col1 IN (1,2) )
UNION DISTINCT -- since there are likely to be dups
( SELECT ... WHERE col2 IN (1,2) );
And provide the optimal index for each SELECT:
INDEX(col1),
INDEX(col2)
A composite index of those two columns will not suffice.
(Appologies -- this is probably a summary of best of the many disjointed comments.)

MySQL select to detect mutually exclusive row conflicts within groups

With the following sample data, I want to create a query that can find where item/desc is duplicate and their respective data fields are not mutually exclusive. Meaning... there can be only 1 data value in column for a given combination of item/desc.
Sample table records:
id | item | desc | data1 | data2 | data3
----+-------+-------+-------+-------+-------
1 | 1 | cat | a | |
2 | 1 | cat | | b |
3 | 1 | cat | | e |
4 | 2 | dog | a | |
5 | 2 | dog | | h | f
6 | 3 | apple | k | | m
7 | 3 | worm | a | g | x
8 | 4 | rock | p | | s
9 | 4 | rock | | | s
10 | 4 | rock | | t | z
Expected query result:
item | desc
-------+-------
1 | cat (because of conflict in data2 with b & e)
4 | rock (because of conflict in data3 with s,s & z
This should work:
select distinct
item,
`desc`
from
table
group by item, `desc`
HAVING count(distinct data1) > 1 or count(distinct data2) > 1 or count(distinct data3) > 1
You could do simple count aggregation and HAVING clause to achieve this.
SELECT `item`,
`desc`,
COUNT(`data1`) AS `data1count`,
COUNT(`data2`) AS `data2count`,
COUNT(`data3`) AS `data3count`
FROM table
GROUP BY `item`, `desc`
HAVING `data1count` > 1
OR `data2count` > 1
OR `data3count` > 1

Merge 2 different mysql tables

I have two tables:
Table a:
+----+------+
| id | data |
+----+------+
| 1 | 450 |
| 2 | 500 |
| 3 | 550 |
| 4 | 600 |
| 5 | 650 |
+----+------+
Table b:
+----+------+------+
| id | a_id | note |
+----+------+------+
| 1 | 2 | 25 |
| 2 | 5 | 10 |
+----+------+------+
I need a query that returns a table that consists of every row from table a with the notes from table b. I want 0 filled in where a note isn't available on a row. I want it to look like this:
+----+------+------+
| id | data | note |
+----+------+------+
| 1 | 450 | 0 |
| 2 | 500 | 25 |
| 3 | 550 | 0 |
| 4 | 600 | 0 |
| 5 | 650 | 10 |
+----+------+------+
How do I do that?
select a.id, a.data, coalesce(b.note, 0) as note
from a
left join b on a.id = b.a_id
What are you looking for is called LEFT/RIGHT JOIN. This question will give you more details about what they are.
Assume you have a query like:
SELECT * FROM a LEFT JOIN b ON some_condition;
Then, its output will contain every row from table a, along with data from table b where the condition is met. For rows where the condition is not met, the columns with data from b will contain null.

Joining 3 tables from two different Databases?

Database 1 (2 tables) : sandbox_maesc4
table 1: coordinates
+----------------------------------------+
|coord_id | section_name | station_number|
+----------------------------------------+
| 1 | A | A7 |
| 2 | B | B20 |
| 3 | C | C3 |
| 4 | D | D14 |
| 5 | E | E9 |
+----------------------------------------+
table 2: workstation_userlogged
+----------------------------------+
| id | ws | user |
+----------------------------------+
| 1 | COMP123 | ryan |
| 2 | COMP345 | luda |
| 3 | COMP567 | chris |
| 4 | COMP891 | michel|
| 5 | COMP444 | isabel|
+----------------------------------+
Database 2 (1 table): softphone_materials_updater
Table 1: workstation
+----------------------------+
| ID | ws | pod |
+----------------------------+
| 1 | COMP123 | A07 |
| 2 | COMP345 | B20 |
| 3 | COMP567 | C03 |
| 4 | COMP891 | D14 |
| 5 | COMP444 | E09 |
+----------------------------+
Problem:
I only have read access in Database 2.
So I did a SELECT query for both fields and created the table "userlogged".
Now, I want to combine both tables "coordinates" and "userlogged" by joining table "workstation"
with their relation of the "station_number" field and "pod" field from. How can I achieve this? Below is the query that I tried but doesnt work.
I have extra fields in "coordinates" table (X,Y fields with actual coordinates). In PHP I use all fields to show them on screen.
SELECT
coordinate_id,
section_name,
x_coord,
y_coord,
ws.username,
ws.hostname,
w.pod,
FROM
sandbox_maesc4.coordinates c,
sandbox_maesc4.workstation_userlogged ws
INNER JOIN
softphone_materials_updater.workstations w
ON c.station_number = w.pod
I think maybe this is what you want?
SELECT
coordinate_id,
section_name,
x_coord,
y_coord,
wsu.username,
wsu.hostname,
w.pod
FROM
sandbox_maesc4.coordinates c
INNER JOIN
softphone_materials_updater.workstations w
ON c.station_number = w.pod
INNER JOIN
sandbox_maesc4.workstation_userlogged wsu
ON w.ws = wsu.ws
Not sure about the database and table names, they seem to differ between your sample query and the description.