Generating SQL query with given number of rows in a query - mysql

I need to turn my table to this given output table using the column order table.
Is this even possible using SQL only?
I looked up the answer on the internet and I've seen people generally use PIVOT. However, my table has as many columns as there are rows in the column order row. So is this possible?
Any ideas/hints on how to do this are greatly appreciated.
Table I already have (yes, it's sorted by A)
A B C
---------- ---------- ----------------------
1 1 74
1 2 95
2 1 78
2 2 10
2 3 33
Order of Columns (another table I have)
B
-----
2
1
3
Wanted table (sorted by A)
A COLUMN 2 COLUMN 1 COLUMN 3
--------------------------------
1 95 74 0
2 10 78 33

As others pointed out, you need a column in the Order of Columns table representing the order. Assume that column is id, then you can use query:
select t.A,
ifnull(max(if (o.id=1, t.c, null)),0),
ifnull(max(if (o.id=2, t.c, null)),0),
ifnull(max(if (o.id=3, t.c, null)),0)
from t
join t_order o on o.b=t.b
group by t.A
See db-fiddle

Related

How to insert rows for each of the TYPE column?

How to insert rows for each of the type column? If there is two type, type 1 and type 2, then I need to insert two rows and also need to change the order and id value for whole table.
current status:
CHOICE Table
id choice type order
1 AA 1 1
2 BB 1 2
3 CC 1 3
4 AAA 2 4
5 BBB 2 5
6 CCC 2 6
7 DDD 2 7
Required updated table:
Now i wan to insert choice "000" for each type. The updated table will be look like bellow. How can I achieve this?
updated CHOICE Table
id choice type order
1 000 1 1
2 AA 1 2
3 BB 1 3
4 CC 1 4
5 000 2 5
6 AAA 2 6
7 BBB 2 7
8 CCC 2 8
9 DDD 2 9
here, id and order column serialized again.
The actual table is too big, so I cannot insert by edit. Please help for this complex query. I have no clue to solve this.
Use insert . . . select to insert the rows:
insert into choice (choice, type)
select distinct '000', type
from choice;
This assumes that id is automatically assigned (and it will be different from your example).
However, it looks like you want to update the order as well. For this, I would suggest an update:
update choice c join
(select c2.*,
row_number() over (partition by choice order by (order is null) desc, order) as new_order
from choice c2
) c2
on c.id = c2.id
set c.order = c2.new_order;
As an editorial comment, order is a very bad choice for a column name because it is a SQL keyword.

Sum within a column given two or more conditions in MySQL

In MySQL, I am trying to sum values in a column given certain conditions. I have an example of some data below
Team Season Mth Stat
A 1 1 4
A 1 1 4
A 1 2 7
A 1 2 9
B 1 1 6
B 1 1 6
B 1 2 6
B 1 2 9
C 1 1 1
C 1 1 3
C 1 2 3
C 1 2 6
But I need the output to show up as
Team Season Mth Stat
A 1 1 8
A 1 2 16
B 1 1 12
B 1 2 15
C 1 1 4
C 1 2 9
So the Stat column is now the sum of the cells such that Match, Season, and Team are all the same. I have the code below. I see a lot of answers that use 'case' but that seems to be given logical operators that are not equal to each other. When I do it below, now it doesn't recognise the table where the columns are coming from. I do have a inner joins but the data itself is from one table. I get another error as well on the sum function because it requires one argument.
select
Team
,Season
,Match
--this is where I get lost-----------
sum(
select
Stat
From
table
Where
Mth=Mth
AND Season=Season
AND Team=Team
)
--end of getting lost----------------
FROM
table
Where
Season IN (1,2)
GROUP BY
Team
,Season
,Mth
Order BY
Team ASC
Edit:
It turns out I need to use GROUP BY as the comments suggest. So I am not summing within a table, but I sum the variable given the Group By parameters.
Unless I'm missing something, it's simply:
SELECT Team
,Season
,Match
,Sum(Stat)
FROM table
GROUP BY
Team
,Season
,Match
It's simple as this:
SELECT Team,
Season,
Match,
SUM(Stat)
FROM Table
WHERE Season IN (1,2)
GROUP BY Team,
Season,
Match
ORDER BY Team ASC
Please look at the SQL Fiddle example.

How to join two tables with one similar column into one table

I have 3 tables, A and B and C.
sample data for Table A
nid tid
101 3
101 4
101 7
103 3
103 5
104 2
104 4
104 7
sample data for Table B
tid name
2 ram
3 shyam
4 krishna
5 shiv
7 narad
What I want is, in a Third Table C
id nid labels
1 101 shyam, krishna, narad
2 103 shyam, shiv
3 104 ram, krishna, narad
I know how to do this with PHP, but is there any way to do this mysql alone?
Both tables (A and B) have thousands of records and don't have any unique column at the moment.
I tried GROUP_CONCAT but I could not construct desired output.
Edit 1 - I forgot to mention that Table C already has id and nid column inserted, while labels column is empty. So I need help in constructing some query which can update all records of Table C with labels mentioned as above.
Thanks. Regards,
This will insert the records on TableC. Since ID is an autogenerated column, you can omit this in the INSERT clause.
INSERT INTO TableC(Nid, Labels)
SELECT a.nid, GROUP_CONCAT(b.Name) Labels
FROM TableA a
INNER JOIN TableB b
ON a.tid = b.tid
GROUP BY a.nid

MySQL Get rows that do not match with certain conditions

It seems simple in my head but I am at a loss for getting the results I need.
My table
id, code, type
1 1111 1
2 1111 2
3 1222 1 <--- This one
4 1333 1
5 1333 2
6 1444 3 <--- Different type then the others
I want the output of the one that doesn't have a matching code with type 2 but only look for ones with type 1 or type 2 (if that makes sense)
id, code, type
3 1222 1
NOTE: I have over 1 million records to query so I need something fast.
My SqlFiddle
Thanks in advance.
SELECT * FROM codes NATURAL JOIN (
SELECT code
FROM codes
WHERE type IN (1,2)
GROUP BY code
HAVING COUNT(DISTINCT type) = 1
) t
See it on sqlfiddle.
Here is a solution using not exists:
SELECT c.*
FROM codes c
WHERE c.type = 1 and
not exists (select 1
from codes c2
where c2.code = c.code and
c2.type = 2
)

Access Totals Query Not Necessarily Returning First Record

I have a table of data like this:
id user_id A B C
=====================
1 15 1 2 3
2 15 1 2 5
3 20 1 3 9
4 20 1 3 7
I need to remove duplicate user ids and keep the record that sorts lowest when sorting by A then B then C. So using the above table, I set up a temp query (qry_temp) that simply does the sort--first on user_id, then on A, then on B, then on C. It returns the following:
id user_id A B C
====================
1 15 1 2 3
2 15 1 2 5
4 20 1 3 7
3 20 1 3 9
Then I wrote a Totals Query based on qry_temp that just had user_id (Group By) and then id (First), and I assumed this would return the following:
user_id id
===========
15 1
20 4
But it doesn't seem to do that--instead it appears to be just returning the lowest id in a group of duplicate user ids (so I get 1 and 3 instead of 1 and 4). Shouldn't the Totals query use the order of the query it's based upon? Is there a property setting in the query that might impact this or another way to get what I need? If it helps, here is the SQL:
SELECT qry_temp.user_id, First(qry_temp.ID) AS FirstOfID
FROM qry_temp
GROUP BY qry_temp.user_id;
You need a different type of query, for example:
SELECT tmp.id,
tmp.user_id,
tmp.a,
tmp.b,
tmp.c
FROM tmp
WHERE (( ( tmp.id ) IN (SELECT TOP 1 id
FROM tmp t
WHERE t.user_id = tmp.user_id
ORDER BY t.a,
t.b,
t.c,
t.id) ));
Where tmp is the name of your table. First, Last, Min and Max are not dependent on a sort order. In relational databases, sort orders are quite ephemeral.