Update Dynamic column values using select statement - mysql

I have two temp table: temp1 and temp 2.
temp 1 is
Reg Key | Player Name | Age
----------------------------
1 | Null | Null
2 | Null | Null
3 | Null | Null
temp 2 is
Reg Key | Question Name | value
----------------------------
1 | Player Name | Ronaldo
2 | Player Name | Zedan
1 | Age | 35
2 | Age | 38
in temp 1 the column name is dynamic except for [Reg Key], for example I need to update the row with [Reg Key] 1 in temp 1 with 'Ronaldo' and 35 from the table temp 2.
I used to loop to get the values from temp 2 and update temp 1, but the records in the table temp 2 now exceed 5 thousand, so I'm trying to create an UPDATE query, but I don't know how to get the columns name at run time.

It sounds like pivot might do the trick:
select 1 as regkey, 'Player Name' as Question_name, 'Ronaldo' as value into #temp2
union all select 2, 'Player Name', 'Zedan'
union all select 1, 'Age', '35'
union all select 2, 'Age', '38'
Select
regkey
, [Player Name]
, [Age]
From #temp2
Pivot (max(value) for Question_Name in ([Player Name], [Age])) as pvt

Related

How to join with a group by and where, including 0 values

I've got some sort of static table like:
SELECT * FROM targets;
name | target
name1 | 6
name2 | 3
name3 | 2
and another table with the actual records inside, that I want to measure:
SELECT * FROM records;
id | name | created_on
546 | name1 | 2022-06-02
547 | name2 | 2022-06-04
548 | name2 | 2022-06-07
Now I'd like to build a table, that groups / counts the records per name (per month).
The group by is easy (except the 0 values):
SELECT "name", COUNT("id") FROM "records"
WHERE MONTH("created_on") = MONTH(CURRENT_DATE())
AND YEAR("created_on") = YEAR(CURRENT_DATE())
GROUP BY "name"
But how do I join both tables to get a result like this?
name | target | current
name1 | 6 | 1
name2 | 3 | 2
name3 | 3 | 0
your data
CREATE TABLE targets(
name VARCHAR(70) NOT NULL
,target INTEGER NOT NULL
);
INSERT INTO targets
(name,target) VALUES
('name1',6),
('name2',3),
('name3',2);
CREATE TABLE records(
id INTEGER NOT NULL
,name VARCHAR(70) NOT NULL
,created_on DATE NOT NULL
);
INSERT INTO records
(id,name,created_on) VALUES
(546,'name1','2022-06-02'),
(547,'name2','2022-06-04'),
(548,'name2','2022-06-07');
you should use Join(Left or Right) to include all values including null values and IF logical operator and Subquery to act as table for your query
SELECT targets.name,
target,
IF(current IS NULL, 0, current) AS current
FROM targets
LEFT JOIN (SELECT name,
Count(id) current
FROM records
WHERE Month(created_on) = Month(CURRENT_DATE())
AND Year(created_on) = Year(CURRENT_DATE())
GROUP BY name) records
ON records.name = targets.name
dbfiddle

Select locations where the user doesn't have it bound yet from 3 tables

I have 3 tables
User Info
id
name
1
bob
2
jane
3
tom
Locations
id
name
1
Test1
2
Test2
3
Test3
4
Test4
User Locations
userID
locationID
1
1
1
2
2
3
Basically What I am trying to achieve is to pull the location names where the user doesn't have it bound already.
In the above list Bob has 2 locations bounded "test 1" and "test 2" but he doesn't have "test 3" or "test 4" yet. I Only want the data to return test 3 and 4 since those are the only ones Bob doesn't have.
For Jane She only has Test 3 bounded but none of the remaining 3
Originally I had tried this and it somewhat worked. However Every time another user gets an unbounded location the its removed from the list. I'm not sure how I would add the user ID in all this so it's only specific to that user.
SELECT `name` FROM `locations`
WHERE `id` NOT IN (SELECT `locationID` FROM `user_locations`)
Create a cartesain product of the user and locations table (cross join), then using an outer join allows us to find rows that are as yet unmatched in user_locations:
select
user_info.ID AS UserID
, locations.ID AS locationID
from user_info
cross join locations
left outer join user_locations on user_info.id = user_locations.userid
and locations.id = user_locations.locationid
where user_locations.userid IS NULL
and user_info.name = 'bob'
SQL Fiddle
MySQL 5.6 Schema Setup:
CREATE TABLE user_info(
id INTEGER NOT NULL PRIMARY KEY
,name VARCHAR(4) NOT NULL
);
INSERT INTO user_info(id,name) VALUES (1,'bob');
INSERT INTO user_info(id,name) VALUES (2,'jane');
INSERT INTO user_info(id,name) VALUES (3,'tom');
CREATE TABLE locations(
id INTEGER NOT NULL PRIMARY KEY
,name VARCHAR(5) NOT NULL
);
INSERT INTO locations(id,name) VALUES (1,'Test1');
INSERT INTO locations(id,name) VALUES (2,'Test2');
INSERT INTO locations(id,name) VALUES (3,'Test3');
INSERT INTO locations(id,name) VALUES (4,'Test4');
CREATE TABLE user_locations(
userID INTEGER NOT NULL
,locationID INTEGER NOT NULL
);
INSERT INTO user_locations(userID,locationID) VALUES (1,1);
INSERT INTO user_locations(userID,locationID) VALUES (1,2);
INSERT INTO user_locations(userID,locationID) VALUES (2,3);
Query 1:
select
user_info.ID AS UserID
, locations.ID AS locationID
from user_info
cross join locations
left outer join user_locations on user_info.id = user_locations.userid
and locations.id = user_locations.locationid
where user_locations.userid IS NULL
order by 1,2
Results:
| UserID | locationID |
|--------|------------|
| 1 | 3 |
| 1 | 4 |
| 2 | 1 |
| 2 | 2 |
| 2 | 4 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
| 3 | 4 |

Select data from single column as multiple record

I have the following table structure in a mysql database.
id | files | status
1 a.pdf,b.pdf,c.pdx 1
2 d.pdf,e.pdf.g.pdf 2
3 x.pdf,k.pdf,y.pdf 1
As you can see, the attachments are all stored on a single line.
My query is supposed to select all rows where status = 1 so i'm expecting the data in the following format.
1 1 a.pdf 1
2 1 b.pdf 1
3 1 c.pdf 1
4 3 x.pdf 1
5 3 k.pdf 1
6 3 y.pdf 1
Unfortunately, I am unsure which operator I can use to accomplish this. I'm aware SQL has pivot but i doubt even that can address my issue.
As a result, I would appreciate if I could get any help in the condition of the select query.
Regards
Try this:
SET #row_num = 0;
SELECT
(#row_num := #row_num + 1) ROW_NUM,
id,
SUBSTRING_INDEX(SUBSTRING_INDEX(files, ',', idx), ',', -1) FileName,
status
FROM
test
JOIN
(SELECT 1 idx UNION ALL SELECT 2 idx UNION ALL SELECT 3 idx UNION ALL SELECT 4 idx UNION ALL SELECT 5 idx) idxs
on idxs.idx - 2 < LENGTH(files) - LENGTH(REPLACE(files, ",", ""))
WHERE status = 1
;
Just add as many indexes as your max count of files in a string.
Note that there should be no comma fater last filename. This is magic -2 is responsible for.
Consider the following...
I have a table (ints) of integers (0-9)...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,files VARCHAR(100) NOT NULL
,status INT NOT NULL
);
INSERT INTO my_table VALUES
(1,'a.pdf,b.pdf,c.pdx',1),
(2,'d.pdf,e.pdf,g.pdf',2),
(3,'x.pdf,k.pdf,y.pdf',1);
SELECT DISTINCT id
, SUBSTRING_INDEX(SUBSTRING_INDEX(files,',',i2.i*10+i1.i+1),',',-1) file
, status
FROM my_table
, ints i1
, ints i2
WHERE status = 1
ORDER
BY id, i2.i*10+i1.i;
+----+-------+--------+
| id | file | status |
+----+-------+--------+
| 1 | a.pdf | 1 |
| 1 | b.pdf | 1 |
| 1 | c.pdx | 1 |
| 3 | x.pdf | 1 |
| 3 | k.pdf | 1 |
| 3 | y.pdf | 1 |
+----+-------+--------+

MYSQL Removing duplicates in mixmatched order

How can I remove duplicates in the following order
1 2
2 1
1 3
4 1
and only output
1 2
1 3
4 1
Consider the following...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,user1 INT NOT NULL
,user2 INT NOT NULL
);
INSERT INTO my_table (user1,user2) VALUES
(1, 2),
(2, 1),
(1, 3),
(4, 1);
SELECT x.*
FROM my_table x
JOIN
( SELECT MIN(id) id
FROM my_table
GROUP
BY LEAST(user1,user2)
, GREATEST(user1,user2)
) y
ON y.id = x.id;
+----+-------+-------+
| id | user1 | user2 |
+----+-------+-------+
| 1 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 4 | 1 |
+----+-------+-------+
Use GROUP BY to merge duplicate.
You can use the DISTINCT clause to remove duplicates. The DISTINCT command in SQL retrieves unique data from your table. To remove duplicates, you can issue a statement similar to below:
SELECT DISTINCT Column_Name
FROM Table_Name
OUTPUT: 1 2 OR 2 1
Please let me know if this helps.

How to group subsequent rows (based on a criteria) and then count them [MySQL]?

Let's say I have such a table (ordered by date):
id | name | type | date
1 | A | 1 | 01-08-2012
2 | A | 2 | 01-08-2012
3 | B | 1 | 02-09-2012
4 | A | 1 | 01-10-2012
5 | A | 4 | 01-10-2012
6 | A | 5 | 02-10-2012
I want to group subsequent rows that have the same 'name' value and count them:
name | count
A | 2
B | 1
A | 3
I was thinking about writing a stored procedure and using cursors, but I was also wondering, if there's a simpler solution, for example using nested SELECTs, etc.
My question is very similar to: how to group array and count them, but that one concerns PHP.
To do that I used a couple of variables,
the table structure, I created my own just for testing and it's:
create table abc (id int, name varchar(20),type int);
insert into abc values
( 1 , 'A' , 1 ),
( 2 , 'A' , 2 ),
( 3 , 'B' , 1 ),
( 4 , 'A' , 1 ),
( 5 , 'A' , 4 ),
( 6 , 'A' , 5 )
the query ended being like this:
set #a:='';
set #counter:=1;
set #groupby:=0;
select *,count(REPEATED) from (select name,if(#a=name,#counter:=#counter+1,#counter:=1) as rep,if(#counter=1,#groupby:=#groupby+1,#groupby) as repeated,#a:=name type from abc) as t group by repeated
you can see it works in SQLFIDDLE if you have any question let me know.
In the SQLFIDDLE