multiple rows into columns mysql - mysql

Hi I am trying to create a mysql query that will convert multiple rows in a table to unique columns
The data I have is as follows:
The table I would like to see is as follows:
GEID|Username|First Name|Last Name|Email|Country|Dealer Code

The statement which could be used is
UPDATE table_name
SET column1 = value 1 , column 2 = value 2 ...
Where condition;
Sorry but my SQL isn't the best but hope the statement helps

This is a real pain, because you don't have an id identifying groups that are the same. In other words, you are missing the entity id.
I think you can construct one by counting the number of GEID values before any given row. The rest is just aggregation:
select max(case when fieldname = 'GEID' then fieldData end) as GEID,
max(case when fieldname = 'Username' then fieldData end) as Username,
. . .
from (select t.*,
(select count(*) from t t2 where t2.id <= t.id and t2.fieldName = 'GEID'
) as grp
from t
) t
group by grp;

Related

SQL pivot output result set of a COUNT in MySQL without UNION nor GROUP BY

I'm working on couple of millions of lines so I won't use an UNION to display my query as I would like.
For design purposes I need this query returned in a certain way to upload automatically a pie chart.
Query:
SELECT
COUNT(IF( b IS NULL, id , NULL)) AS 'not_assigned',
COUNT(IF(b IS NOT NULL, id, NULL)) AS 'assigned'
FROM table
WHERE
OverType = "abc"
AND Type = "def"
AND Sub_Type = "ghi"
AND Date BETWEEN "2022-12-01" AND "2022-12-25"
AND Client LIKE '%john%';
Result set:
not_assigned assigned
1000 500
So I would like to transform the output as this:
Count
not_assigned 1000
assigned 500
Any advice for a MySQL version 5.0?
You may aggregate by a CASE expression:
SELECT
CASE WHEN b IS NULL THEN 'not_assigned' ELSE 'assigned' END AS category,
COUNT(*) AS cnt
FROM yourTable
WHERE
OverType = 'abc' AND
Type = 'def'
Sub_Type = 'ghi' AND
Date BETWEEN '2022-12-01' AND '2022-12-25' AND
Client LIKE '%john%'
GROUP BY 1;

I need to compare 2 tables in MySql and dispaly the differences

both tables table_a and table_b has to be compared using employee_id column which is present in both of them.
Both Tables have MILLIONS of rows.
3 Results must be displayed-
employee_id present in table_a but not present in table_b.
vice-versa.
there would be case when a particular employee_id is present in both tables but the data in other columns for that employee_id might not be same in both tables. These rows must also be displayed showing the columns where there is data mismatch.
Since there are millions of rows in both tables, the process must be fast so that both tables can be compared quickly.
I am using MySQL server to write query.
This is rather tricky, but here is an example assuming that employee_id is unique in each table:
select employee_id,
(case when max(which) = 'a' then 'A-only'
when min(which) = 'b' then 'B-only'
else 'both'
end) as which,
concat_ws(',',
(case when count(*) = 2 and not min(col1) <=> max(col1) then 'col1' end),
(case when count(*) = 2 and not min(col2) <=> max(col2) then 'col2' end)
) as differences
from ((select 'a' as which, employee_id, col1, col2
from a
) union all
(select 'b' as which, employee_id, col1, col2
from b
)
) ab
group by employee_id;
Note that this uses the NULL-safe comparison operator.

Dynamically creating columns from row data using Select in Bigquery

Background
I want to rename my case statement in sql select statement dynamically.
Eg:
SELECT (case when id= x.id then x.sums end) x.id
as (select id,count(*) sums from table
group by id) x
what i want the output is list of columns created ,with Labels as distinct id's from "id" column.
However,this variable x.id is not dynamically outputing values,rather i get output a single column x.id.
Eg:
Columns in table...
id---c1----c2
1----x1---x2
2----x2----x3
3----x4----x5
columns expected after running query...
1-----2----3
but actual o/p column is::
x.id
Query
Any ideas,how to generate columns dynamically using select query,please correct me ,if i am wrong.
Below is for BigQuery!
Please note: your expectations about output column names are not correct!
Column name cannot start with digit - so in below example - i will be using id_1, id_2 and id_3 instead of 1, 2 and 3
SELECT
SUM(CASE WHEN id = 1 THEN 1 END) AS id_1,
SUM(CASE WHEN id = 2 THEN 1 END) AS id_2,
SUM(CASE WHEN id = 3 THEN 1 END) AS id_3
FROM YourTable
Above example assumes you know in advance your IDs and there are very few of them so it is not a big deal to write manually few numbers of lines with SUM(...) for each id
If this is not a case - you can first generate above query programmatically by running below query
SELECT 'SELECT ' +
GROUP_CONCAT_UNQUOTED(
'SUM(CASE WHEN id = ' + STRING(id) + ' THEN 1 END) AS id_' + STRING(id)
)
+ ' FROM YourTable'
FROM (
SELECT id FROM (
SELECT * FROM YourTable GROUP BY id ORDER BY id
)
as a result - you will get string like below
SELECT SUM(CASE WHEN id = 1 THEN 1 END) AS id_1,SUM(CASE WHEN id = 2 THEN 1 END) AS id_2,SUM(CASE WHEN id = 3 THEN 1 END) AS id_3 FROM YourTable
So, now just copy it and paste into Query Editor and run it
you can see similar example here - https://stackoverflow.com/a/36623258/5221944

using select statement in then clause of case

I'm trying to include select statement in the then of case statement but the output is not as expected. I know there is different method to do this but can it be done the way i'm trying to do.
Using the following example data:
create table example(name varchar(10));
insert into example values
('abc'),('bcd'),('xyz');
I have tried this query (here is the fiddle):
select
case when ((select * from example where name='abc')>=1)
then (select * from example where name='abc')
else (select count(*) from example)
end
from example
But it outputs
3
3
3
Expected output if name='abc' exist
name
abc
if not the count(*)
Thanks in advance
Your subquery in the example is (select * from example where name='abc') which is a result set, not a scalar value. Currently it "works" because it is comparing the only column in the table to the value 1 but if you had more than one column in the table it would error out. Perhaps you intended (select count(*) from example where name='abc')?
Similarly, the THEN clause in a case can only be used to provide a single column value. In order to do this, perhaps you meant the following:
select
case when exists (select * from example where name='abc')
then (select name from example where name='abc')
else (select count(*) from example)
end
from example
But even here you will get three rows and there is no correlation between the rows in example and the result set, so I am not really sure what you're trying to do. I imagine there is a higher purpose though so I will leave it at that.
This should do the trick
select distinct
case when ((select count(name) from example where name='abc')>=1)
then (select * from example where name='abc')
else (select count(*) from example)
end
from example
Let me know if it works.
Point 1:
For the query, you are trying, the from example in the last will cause to loop through all the records and fetch all the records. To restrict that, you have to remove that.
Point 2:
You can't combine multi row select * in a true condition with a single row count(*) in a false condition. You should limit to select a single row.
Example:
select
case when ( select count(*) from example where name='abc' ) >= 1
then ( select * from example where name='abc' limit 1 )
else ( select count(*) from example )
end as name
No need to bother with the complex queries.
SELECT COUNT(*) AS ct
FROM example
GROUP BY name = 'abc'
ORDER BY name = 'abc' DESC
LIMIT 1;
If you really want to use CASE just for the sake of using it:
SELECT
CASE name
WHEN 'abc' THEN 'abc'
ELSE 'others'
END AS name, COUNT(*) AS ct
FROM example
GROUP BY name = 'abc'
ORDER BY name = 'abc' DESC
LIMIT 1;
Try below query, which will work even you enter a second duplicate row as value 'abc'. Mostly above suggested queries will not work as you enter this duplicate row while as per your query condition (>=1), there can be multiple rows for name as 'abc'.
SELECT
CASE WHEN b.cnt>=1
THEN a.name
ELSE (SELECT COUNT(*) FROM EXAMPLE)
END
FROM (SELECT DISTINCT NAME FROM EXAMPLE WHERE NAME='abc') a
JOIN (SELECT NAME,COUNT(*) AS cnt FROM EXAMPLE WHERE NAME='abc') b
ON a.name=b.name

MySQL - Matching 2 rows (or more!) within a sub-query/table

I have this schema which I need to match 2 rows from
user_data : user_id, field_id, value
A sample output would be:
user_id field_id value
-----------------------------
1 1 Gandalf
1 2 Glamdring
How do I write a query which basically say "Find the user id of the user whose field_id 1 is Gandalf, and field_id 2 is Glamdring?"
SELECT FROM looks at one row at a time. I am stumped on this. I will also need to find a solution that scale gracefully (such as looking at three rows etc.)
You could run a query to get the users that match each of the conditions and intersect the results. Since MySQL doesn't support intersect you can do it with an n-way join:
SELECT T1.user_id
FROM Table1 T1
JOIN Table1 T2 ON T1.user_id = T2.user_id
WHERE T1.field_id = 1 AND T1.value = 'Gandalf'
AND T2.field_id = 2 AND T2.value = 'Glamdring'
I would try the following:
SELECT user_id
FROM user_data
WHERE ( field_id = 1 AND value= 'Gandalf' )
OR ( field_id = 3 AND value = 'Glamdring' )
GROUP BY user_id
HAVING COUNT( field_id ) = 2
It will search for all the rows that match one of your criteria, and use GROUP BY and HAVING afterwards to find the user_id that has the expected count of matches.
select * from user_date where ( field_id= 1 AND value='Gandalf' ) OR ( field_id =2 AND value ='Glamdring' ) ;
The HAVING clause is the key. It turns the query from an "OR" statement into an "AND" statement