I've 2 tables, they both have a structure similar to this one
id | content | date
However I would like to a make a query where the 2 tables are mixed together and ordered by their date
for example in the TABLE_A I've (1,Joe,20-11-2020)/(2,John,20-11-2021) TABLE_B has (1,Luke,20-11-2010)/(1,Mark,20-11-2011) The result I want to see is: (1,Luke,20-11-2010)/(1,Mark,20-11-2011)/(1,Joe,20-11-2020)/(2,John,20-11-2021)
SELECT T.ID,T.CONTENT,T.DATE
FROM TABLE_1 AS T
UNION ALL
SELECT A.ID,A.CONTENT,A.DATE
FROM TABLE_2 AS A
ORDER BY 3
try this:
select id, content, date
from (
select id, content, date
from tab_A
union all
select id, content, date
from tab_B
) C order by date
use "union" instead of "union all" if you are not interest to have duplicates rows
Related
i have two tables (table1 and table2) with common column customer_id, with union and few filters i am getting all the values from table 1 and table2. I need only rows where both the tables have the data based on the common column customer_id. Below is the example.
The output that I need is as follows
Here's what I've tried:
SELECT customer_id,
age,
amount,
type
FROM table1
WHERE age > 5
UNION
SELECT customer_id,
age,
amount,
type
FROM table2
WHERE age > 5
Your query combines the rows of the two tables but doesn't match customers present in both. What you need to add is the condition on the "customer_id" being present in the corresponding other table:
SELECT *
FROM table1
WHERE age > 5 AND customer_id IN (SELECT customer_id FROM table2)
UNION
SELECT *
FROM table2
WHERE age > 5 AND customer_id IN (SELECT customer_id FROM table1)
You should choose between:
UNION, if you want to return unique rows between the two tables - makes an additional aggregation operation
UNION ALL, if you want to allow repeated rows between the two tables
If you don't have repeated identical rows in your tables, then you should go with the most efficient one, which is UNION ALL.
I use mysql db engine, I wonder is it possible that the data in the table one row transferred to another table, this table would consist of two columns, id and value
each of the transferred value would go into one row and row would look like ID, value, and for as long as it has a value that is transferred to new row maintains the id as long as it has a value that belonged to the id of a row from which it transferred
Initial table looks like
id |country_name |city_1 |city_2 |city_3 |city_4
------------------------------------------------------------------------
1 |Some_country |some_city1 |some_city2 |some_city3 |some_city4
Wanted table looks like
id | city_name
1 | some_city1
1 | some_city2
1 | some_city3
1 | some_city4
Use this for one particular ID
select id, city_name from(
select id, city_1 as city_name from yourTable
union all
select id, city_2 from yourTable
union all
select id, city_3 from yourTable
union all
select id, city_4 from yourTable
) as t where id= yourID
http://sqlfiddle.com/#!9/7ee1f/1
Use this for whole table
select id, city_name from(
select id, city_1 as city_name from yourTable
union all
select id, city_2 from yourTable
union all
select id, city_3 from yourTable
union all
select id, city_4 from yourTable
) as t
order by id
What you are looking for is often referred to as vertical pivoting: you want to pivot something like an array of four city names - hard-wired into the table definition - into four vertical rows.
The solution is a cross join with a temporary table with as many consecutive integers, starting from 1, as you have columns to pivot, in conjunction with a CASE-WHEN expression that makes use of that series of integers.
See here:
WITH foo(id,country_name,city_1,city_2,city_3,city_4) AS (
SELECT 1,'Some_country','some_city1','some_city2','some_city3','some_city4'
)
, four_indexes(idx) AS (
SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
)
SELECT
id AS country_id
, idx AS city_id
, CASE idx
WHEN 1 THEN city_1
WHEN 2 THEN city_2
WHEN 3 THEN city_3
WHEN 4 THEN city_4
ELSE ''
END AS city_name
FROM foo CROSS JOIN four_indexes
;
country_id|city_id|city_name
1| 1|some_city1
1| 3|some_city3
1| 2|some_city2
1| 4|some_city4
Only the other day, I answered a question that was looking for reversing the operation we are performing here: horizontal pivoting.
See here if you're curious ...
How to go about a column with different values in a same row in sql?
Happy Playing -
Marco the Sane
Here is my query:
SELECT t.id, t.phone
FROM tablename t
It results in duplicate IDs because in one column there are two or more different values in it.
ID Phone
1 540-500-5000
1 540-888-8888
2 340-600-6000
2 340-777-7777
3 210-200-2000
4 950-600-6000
4 950-444-4444
I want to select just the first phone for each ID, in order to avoid duplicated rows just because there are two or more phones under the same ID.
Desired output:
ID Phone
1 540-500-5000
2 340-600-6000
3 210-200-2000
4 950-600-6000
SQL Fiddle:
SELECT t.id, MIN(t.phone)
FROM tablename t
GROUP BY t.id
SELECT ID, MIN(phone) MinIsTheFirst
FROM tableName
GROUP BY ID
Just having fun with the word "FIRST"
Try this:
select ID, MIN(Phone)
from tablename
group by ID
This will give you what you want if you don't care which phone is returned. If you have a way of determining the first phone, we can adjust.
just a quick question:
i have to have one single query that has multiple rows - some rows are identicle - and the order of rows must be preserved in the result -
some idea of what im refering to:
SELECT id,date
FROM items
WHERE id IN (1,2,1,3)
ORDER BY id=1 DESC,id=2 DESC,id=1 DESC,id=3 DESC;
unfortunately mysql result is this:
1,2,3
not 1,2,1,3
it removes the duplicate which i have to have in my result to display in multiple panels on the same webpage -
i really dont want to loop thru each id one by one to get them the way i want to display -
is there a way to actually have one single query that will preserve the order and pull out rows based on request whether its unique or not -
Your query as it stands will never work, because duplicate values in a list of values of an IN clause are ignored. The only way to make this work is by using UNION ALL:
SELECT id, date FROM items where id = 1
UNION ALL
SELECT id, date FROM items where id = 2
UNION ALL
SELECT id, date FROM items where id = 1
UNION ALL
SELECT id, date FROM items where id = 3;
But to be frank, I suspect your data model so far past screwed it's unusable.
try
SELECT
id,
date
FROM items
WHERE id IN (1,2,1,3)
ORDER BY FIND_IN_SET(id, '1,2,1,3')
Another scrupulous way to answer a suspicious question:
SELECT
items.id,
items.date
FROM
items
JOIN
( SELECT 1 AS id, 1 AS ordering
UNION ALL
SELECT 2, 2
UNION ALL
SELECT 1, 3
UNION ALL
SELECT 3, 4
) AS auxilary
ON
auxilary.id = items.id
ORDER BY
auxilary.ordering
Another approach (untested, but should give you the idea):
CREATE TEMPORARY TABLE tt (id INT, ai int unsigned auto_increment primary key);
INSERT INTO tt (id) VALUES (1), (2), (1), (3);
SELECT
id,
date
FROM items JOIN tt USING (id)
ORDER BY tt.ai;
keeps the given order.
If you want to include the records with id=1 and the order doesn't matter as long as you get them, you can split your query into two queries, one for (1,2,3) union all the other query for id=1 or just do:
... In (1,2)
Union all
... In (1,3)
Example:
Select * from
(Select case id when 1 then 1 when 2 then 2 as pseudocol, othercolumns
From table where Id in (1,2)
Union all
Select case id when 1 then 3 when 3 then 4 as pseudocol, othercolumns
From table where Id in (1,3)) t order by pseudocol
Instead of doing what you are trying to, just select the unique rows you need. In the frontend code, store each unique row once in a key=>value structure, where key is the item ID and value is whatever data you need about that item.
Once you have that you can use frontend logic to output them in the desired order including duplicates. This will reduce the amount of redundant data you are trying to select.
For example This is not usable code - exact syntax required depends on your scripting language
-- setup a display order
displayOrder= [1,2,1,3];
-- select data from database, order doesn't matter here
SELECT id,date
FROM items
WHERE id IN (displayOrder);
-- cache the results in a key=> value array
arrCachedRows = {};
for (.... each db row returned ...) {
arrCachedRows[id] = date;
}
-- Now output in desired order
for (listIndex in displayOrder) {
-- Make sure the index is cached
if (listIndex exists in arrCachedRow) {
echo arrCachedRows[listIndex ];
}
}
If you must persist in using UNION despite my warnings
If you go against the above recommendation and absolutely MUST have them back in 1 query in that order then add on an additional row which will enforce the row order. See below query where I use variable #subIndex to add an incrementing value as subIndex. This in turn lets you reorder by that and it'll be in the requested order.
SELECT
i.*
FROM (
SELECT #subIndex:=#subIndex+1 AS subIndex, id, date FROM items where id = 1
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, id, date FROM items where id = 2
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, id, date FROM items where id = 1
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, id, date FROM items where id = 3
) AS i,(SELECT #subIndex:=0) v
ORDER BY i.subIndex
Or a slightly cleaner version that keeps item selection until the outside and hides the subindex
SELECT
items.*
FROM items
-- initialise variable
INNER JOIN (SELECT #subIndex:=0) v
-- create a meta-table with the ids desired in the order desired
INNER JOIN (
SELECT #subIndex:=#subIndex+1 AS subIndex, 1 AS id
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, 2 AS id
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, 1 AS id
UNION
SELECT #subIndex:=#subIndex+1 AS subIndex, 3 AS id
) AS i
ON i.id = items.id
-- order by the subindex from i
ORDER BY i.`subIndex` ASC
ok, this is kind of complicated to explain, i will try my best, you are welcome to ask questions if you dont understand me.
i have a table desiged like this:
TITLE | BRANCH | BRANCH1 | BRANCH2 | BRANCH3
a BRANCH (any of them) might contain "bank","credit" and so on
what i want to do, is return rows with distinct branches and count, where the title equals "xxx"
something like:
BANK | xxx Results
CREDIT | xxx Results
and so on.
If you can't alter your tables to conform to 1FN, following should get you started
UNPIVOT the columns using a UNION ALL giving you a resultset that conforms to 1FN.
Make this into a subselect
Filter on the TITLE from this subselect
GROUP BY and COUNT the results
SQL Statement
SELECT BRANCH, COUNT(*)
FROM (
SELECT TITLE, BRANCH FROM MyTable
UNION ALL SELECT TITLE, BRANCH1 FROM MyTable
UNION ALL SELECT TITLE, BRANCH2 FROM MyTable
UNION ALL SELECT TITLE, BRANCH3 FROM MyTable
) q
WHERE TITLE = 'ATitle'
GROUP BY
BRANCH