Joining values of columns? - mysql

I have a query that fetches the list of user IDs and their corresponding user names on a board but from another table also gets a column that has a value (a name) on the row corresponding to the user ID if said user has changed their name. Using an outer join I got the three nicely displayed as in the following example of a few of the results:
member_id name dname_current
1 Blablabla1 blablabla2
2 Bla4444
3 RevZ
5 Herpaderp42
6 Lalalala
7 Kaboom
14 testtesttest21 Formula21
15 Alex Ethan
16 Bob Radio3
The SQL query to get the three columns is as follows:
SELECT
data_members.member_id,
data_members.name,
data_dnames_change.dname_current
FROM data_members LEFT OUTER JOIN data_dnames_change
ON data_members.member_id = data_dnames_change.dname_member_id
GROUP BY data_members.member_id
Is there a way to display this so that it merges the values which exist in the 'dname_current' column of that other table into the 'name' column, replacing any value that's already in the corresponding row of that column?

COALESCE() returns the first non-null value, so you can do the following to prefer dbname_current over data_members.name unless it is NULL:
SELECT
data_members.member_id,
COALESCE(data_dnames_change.dname_current, data_members.name) AS name
FROM data_members LEFT OUTER JOIN data_dnames_change
ON data_members.member_id = data_dnames_change.dname_member_id
GROUP BY data_members.member_id
Should return:
member_id name
1 blablabla2
2 Bla4444
3 RevZ
5 Herpaderp42
6 Lalalala
7 Kaboom
14 Formula21
15 Ethan
16 Radio3

Related

Merge two colums result as single colum data using Mysql query

I want to get all record data as single column using SQL query.User Table
user_id username parent_id
10 user1 5
12 user2 3
14 user3 2
.. .. ..
get all users with parent id as single column
Need results as below (get data from user_id & parent_id)
users OR users
10 10
12 5
14 12
5 3
3 14
2 2
.. ..
Here just need list of user sequence is not important.Is this possible in sql query? is there any SQL function for that?
This will do the trick.
SELECT user_id AS users FROM Users
UNION
SELECT parent_id AS users FROM Users
Use UNION ALL if you need duplicate values (such as in the parent_id column) to return as individual rows. Make sure the alias is the same for both halves to get it to return in a single column. This will return unordered, so rerunning the query might not always give the same result (meaning same data in same order), but it will always give the same data.

Working of SQL JOINS in this example

Ok so i was learning sql joins and was curious to try all joins on the following table:
Table name Demo1:
A
1
1
1
1
1
Table name Demo2:
B
1
1
1
1
1
To my amazement no matter which join i apply i end up with same 25 entries. I am sure about cross join since it gives all combination but what about the other joins how are they returning the same answers for these two tables.
How join statement work is it pick up all entries from the first table
the for every entry, it pick all entries from the second table that is sastified by the on condition.
Hence, the number of result in this case = number of records in A * number of records in B = 25.

SQL Validate a column with the same column

I have the following situation. I have a table with all info of article. I will like to compare the same column with it self. because I have multiple type of article. Single product and Master product. the only way that I have to differences it, is by SKU. for example.
ID | SKU
1 | 11111
2 | 11112
3 | 11113
4 | 11113-5
5 | 11113-8
6 | 11114
7 | 11115
8 | 11115-1-W
9 | 11115-2
10 | 11116
I only want to list or / and count only the sku that are full unique. follow th example the sku that are unique and no have variant are (ID = 1, 2, 6 and 10) I will want to create a query where if 11113 are again on the column not cout it. so in total I will be 4 unique sku and not "6 (on total)". Please let me know. if this are possible.
Assuming the length of master SKUs are 5 characters, try this:
select a.*
from mytable a
left join mytable b on b.sku like concat(a.sku, '%')
where length(a.sku) = 5
and b.sku is null
This query joins master SKUs to child ones, but filters out successful joins - leaving only solitary master SKUs.
You can do this by grouping and counting the unique rows.
First, we will need to take your table and add a new column, MasterSKU. This will be the first five characters of the SKU column. Once we have the MasterSKU, we can then GROUP BY it. This will bundle together all of the rows having the same MasterSKU. Once we are grouping we get access to aggregate functions like COUNT(). We will use that function to count the number of rows for each MasterSKU. Then, we will filter out any rows that have a COUNT() over 1. That will leave you with only the unique rows remaining.
Take that unique list and LEFT JOIN it back into your original table to grab the IDs.
SELECT ID, A.MasterSKU
FROM (
SELECT
MasterSKU = SUBSTRING(SKU,1,5),
MasterSKUCount = COUNT(*)
FROM MyTable
GROUP BY SUBSTRING(SKU,1,5)
HAVING COUNT(*) = 1
) AS A
LEFT JOIN (
SELECT
ID,
MasterSKU = SUBSTRING(SKU,1,5)
FROM MyTable
) AS B
ON A.MasterSKU = B.MasterSKU
Now one thing I noticed from you example. The original SKU column really looks like three columns in one. We have multiple values being joined with hypens.
11115-1-W
There may be a reason for it, but most likely this violates first normal form and will make the database hard to query. It's part of the reason why such a complicated query is needed. If the SKU column really represents multiple things then we may want to consider breaking it out into MasterSKU, Version, and Color or whatever each hyphen represents.

Is it possible to write a query to compare rows to other rows in same table?

I have a table with the following structure. I need to return all rows where the district of the record immediately preceding and immediately following the row are different than the district for that row. Is this possible? I was thinking of a join on the table itself but not sure how to do it.
id | zip_code | district
__________________________
20063 10169 12
20064 10169 9
20065 10169 12
Assuming that "preceding" and "following" are in the sense of the ID column, you can do:
select *
from zip_codes z1
inner join zip_codes z2 on z1.id=z2.id + 1
inner join zip_codes z3 on z1.id=z3.id - 1
where z1.district <> z2.district and z1.district <> z3.district
This will automatically filter out the first and last rows, because of the inner joins, if you need those to count, change it to left outer join.
Also, this checks if it's different from both. To find if it's different from either (as is implied in the comment), change the and in the where clause to an or. But note, that then, all three rows in your example fit that criteria, even if there are long rows of twelves above and below these rows.

SQL GROUP BY - Multiple results in one column?

I am trying to perform a SELECT query using a GROUP BY clause, however I also need to access data from multiple rows and somehow concatenate it into a single column.
Here's what I have so far:
SELECT
COUNT(v.id) AS quantity,
vt.name AS name,
vt.cost AS cost,
vt.postage_cost AS postage_cost
FROM vouchers v
INNER JOIN voucher_types vt
ON v.type_id = vt.id
WHERE
v.order_id = 1 AND
v.sold = 1
GROUP BY vt.id
Which gives me the first four columns I need in the following format.
quantity | name | cost | postage_cost
2 X 5 1
2 Y 6 1
However, I would also like a fifth column to be displayed, showing all of the codes associated with each line of the order like this:
code
ABCD, EFGH
IJKL, MNOP
Where the comma separated values are pulled from the voucher table.
Is this possible?
Any advice would be appreciated.
Thanks
This is what GROUP_CONCAT does.
Assuming the column is called code you would just add ,GROUP_CONCAT(v.code) As Codes to your select list.