How to make record to be table title - mysql

I have this table and its data
----------------------------
| ID | NAME | TYPE | VALUE |
----------------------------
| 1 | A | YES | 10000 |
| 2 | B | NO | 100 |
| 3 | A | NO | 300 |
----------------------------
I wonder how to get data in sql like this :
-----------------------------
| ID | NAME | YES | NO |
-----------------------------
| 1 | A | 10000 | 300 |
| 2 | B | NULL | 100 |
-----------------------------
Please help

You need to pivot the data to do that.
select MIN(ID) as ID, NAME ,
Max(Case when TYPE = 'Yes' then VALUE END) as `Yes`
Max(Case when TYPE = 'No' then VALUE END) as `No`
From Yourtable
Group by NAME
Note: This assumes there are only two possible values(Yes&No) present in TYPE column.

Related

How to replace reference ID with value

Let's say I have two tables:
+------------------------------------+
| `houses` |
+----+-------+-------+-------+-------+
| id | house | room1 | room2 | room3 |
+----+-------+-------+-------+-------+
| 1 | a | 1 | 1 | 2 |
| 2 | b | 1 | 3 | 1 |
| 3 | c | 2 | 2 | 1 |
+----+-------+-------+-------+-------+
+------------------------+
| `status` |
+-------------+----------+
| status_code | status |
+-------------+----------+
| 1 | empty |
| 2 | occupied |
| 3 | full |
+-------------+----------+
Now I want to change room1, room2 and room3's ids to the status from TABLE status like this:
+---------------------------------------------+
| `houses` |
+----+-------+----------+----------+----------+
| id | house | room1 | room2 | room3 |
+----+-------+----------+----------+----------+
| 1 | a | empty | empty | occupied |
| 2 | b | empty | full | empty |
| 3 | c | occupied | occupied | empty |
+----+-------+----------+----------+----------+
I know one solution, but I believe there is an easier way to do the same:
SELECT
h.*,
s1.status AS room1,
s2.status AS room2,
s3.status AS room3
FROM houses h
JOIN status s1 ON h.room1 = s1.status_code
JOIN status s2 ON h.room2 = s2.status_code
JOIN status s3 ON h.room3 = s3.status_code
UPDATE
MySQL pivot table solution is not suitable for me because the above example is a simplified version what I use. There are more than ten different status and writing a 40 line CASE function for a single room is not an opportunity. The status must come from the status table.
You can approach this as
SELECT id,house,
(
CASE
WHEN room1 > 0 THEN (SELECT status FROM status WHERE status_code=room1)
END) AS room1,
(
CASE
WHEN room2 > 0 THEN (SELECT status FROM status WHERE status_code=room2)
END) AS room2,
(
CASE
WHEN room3 > 0 THEN (SELECT status FROM status WHERE status_code=room3)
END) AS room3
FROM houses
Live DEMO

MySQLl key-value store ordering with specific condition

I have the following structure:
+----------+--------+---------------------+
| id| gr_id| name | value |
+----------+--------+---------------------+
| 1 | 11 | name | Burro |
| 2 | 11 | submit | 2019/05/10 |
| 3 | 11 | date | 2019/05/17 |
| 4 | 12 | name | Ajax |
| 5 | 12 | submit | 2019/05/10 |
| 6 | 12 | date | 2019/05/18 |
+----------+--------+---------------------+
I have to order it by the date(if the name is date), from highest to lowest date, also it has to keep the groups (gr_id) without mixing the elments.
The desired result would look like this:
+----------+--------+---------------------+
| id| gr_id| name | value |
+----------+--------+---------------------+
| 4 | 12 | name | Ajax |
| 5 | 12 | submit | 2019/05/10 |
| 6 | 12 | date | 2019/05/18 |
| 1 | 11 | name | Burro |
| 2 | 11 | submit | 2019/05/10 |
| 3 | 11 | date | 2019/05/17 |
+----------+--------+---------------------+
How can i implement this?
You'll have to associate the group ordering criteria with all the elements of the group. You can do it through a subquery, or a join.
Subquery version:
SELECT t.*
FROM (SELECT gr_id, value as `date` FROM t WHERE `name` = 'date') AS grpOrder
INNER JOIN t ON grpOrder.gr_id = t.gr_id
ORDER BY grpOrder.`date`
, CASE `name`
WHEN 'name' THEN 1
WHEN 'submit' THEN 2
WHEN 'date' THEN 3
ELSE 4
END
Join version:
SELECT t1.*
FROM t AS t1
INNER JOIN AS t2 ON t1.gr_id = t2.gr_id AND t2.`name` = 'date'
ORDER BY t2.value
, CASE t1.`name`
WHEN 'name' THEN 1
WHEN 'submit' THEN 2
WHEN 'date' THEN 3
ELSE 4
END

Filter table rows linked to another table via pivot table on basis of where clauses acting on second table

+--------------+
| paintings |
+--------------+
| id | title |
+----+---------+
| 1 | muzelf1 |
| 2 | muzelf2 |
| 3 | muzelf3 |
+----+---------+
+----------------------------------------+
| tags |
+----------------------------------------+
| id | type | name |
+----+-----------------+-----------------+
| 1 | painting_medium | oil_painting |
| 2 | painting_style | impressionistic |
| 3 | painting_medium | mixed_media |
| 4 | painting_medium | watercolours |
| 5 | painting_style | mixed_media |
| 6 | painting_style | photorealistic |
+----+-----------------+-----------------+
+---------------------------+
| paintings_tags |
+---------------------------+
| id | painting_id | tag_id |
+----+-------------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 4 |
| 4 | 3 | 2 |
| 5 | 3 | 1 |
+----+-------------+--------+
sql
CREATE TABLE paintings (
id integer AUTO_INCREMENT PRIMARY KEY,
title text
);
INSERT INTO paintings(id,title) VALUES
(1,'muzelf1'),(2,'muzelf2'),(3,'muzelf3');
CREATE TABLE tags (
id integer AUTO_INCREMENT PRIMARY KEY,
name text,
type text
);
INSERT INTO tags(id,name,type) VALUES
(1,'oil_painting','painting_medium')
,(2,'impressionistic','painting_style')
,(3,'mixed_media','painting_medium')
,(4,'watercolours','painting_medium')
,(5,'mixed_media','painting_style')
,(6,'photorealistic','painting_style');
CREATE TABLE paintings_tags (
id integer AUTO_INCREMENT PRIMARY KEY,
painting_id integer,
tag_id integer
);
INSERT INTO paintings_tags(id,painting_id,tag_id) VALUES
(1,1,1)
,(2,1,2)
,(3,2,4)
,(4,3,2)
,(5,3,1);
Find all the paintings with [{tags.type="painiting_medium", tags.name="oil_painitng"},{tags.type="painiting_style", tags.name="impressionistic"}].
+-----------------------------------+
| Expected Output |
+-----------------------------------+
| id | painting_title | painting_id |
+----+----------------+-------------+
| 1 | muzelf1 | 1 |
+----+----------------+-------------+
| 2 | muzelf3 | 3 |
+----+----------------+-------------+
Here is something I tried doing using bookShelf ORM and knex query builder.
Painting.query(function (qb) {
qb.innerJoin('painting_tags','paintings.id','painting_tags.painting_id')
.innerJoin('tags','painting_tags.tag_id','tags.id')
.where(qb => {
tagFilters.forEach(filter => {
qb.where('tags.type',filter.type).andWhere('tags.name',filter.name)
})
});
});
The above only works if the tag filters array has only one element. But I need it to work for all the filters in the array.
What would a raw query look like for the above? And how can I convert the same to work using ORM and query builder?
Here's one idea:
SELECT p.id painting_id
, p.title
, MAX(CASE WHEN t.type = 'painting_medium' THEN t.name END) medium
, MAX(CASE WHEN t.type = 'painting_style' THEN t.name END) style
FROM paintings p
JOIN paintings_tags pt
ON pt.painting_id = p.id
JOIN tags t
ON t.id = pt.tag_id
GROUP
BY p.id;
+-------------+---------+--------------+-----------------+
| painting_id | title | medium | style |
+-------------+---------+--------------+-----------------+
| 1 | muzelf1 | oil_painting | impressionistic |
| 2 | muzelf2 | watercolours | NULL |
| 3 | muzelf3 | oil_painting | impressionistic |
+-------------+---------+--------------+-----------------+
You could filter this as a subquery (or using HAVING) but, unless the data set was vast, I would be inclined to do the filtering in a bit of javascript.

How to Search parent content from multiple table?

Table - parents
+----+----------+--------------+----------+
| id | user_id | content_type | name |
+----+----------+--------------+----------+
| 1 | 10 | 1 | name - 1 |
| 2 | 12 | 2 | name - 2 |
+----+----------+--------------+----------+
content_type can be
1 = Single part(movies)
2 = Multi prt(serials, episode)
Table - childs
+----+------------+--------------+--------------+-----------+
| id | parent_id | is_episode | episode_name | file_name |
+----+------------+--------------+--------------+-----------+
| 1 | 1 | 0 | NULL | movie.mp4 |
| 2 | 2 | 0 | NULL | zee.mp4 |
| 3 | 2 | 1 | cname-2 | lil-1.mp4 |
| 4 | 2 | 1 | child-2 | lil-2.mp4 |
+----+------------+--------------+--------------+-----------+
And is_episode can be:
0 = No
1 = Yes
NB: some other fields I have skipped
My QUERY:
SELECT F.id,F.user_id,F.content_type,F.name,M.is_episode, M.episode_name, M.file_name
FROM childs M,parents F
WHERE M.parent_id = F.id AND M.is_episode=0 AND
(F.name LIKE '%child%' OR M.episode_name LIKE '%child%' )
Abve MySQL query I am getting 0 record. There is 1 content
My search string applied based on parents.name or childs.episode_name I want to get all record which are is_episode=0 If I search child-2 then findout parent content of my current record. Here is my output should come
+----+----------+----------------+----------+------------+--------------+-----------+
| id | user_id | content_type | name | is_episode | episode_name | file_name |
+----+----------+----------------+----------+------------+--------------+-----------+
| 2 | 12 | 2 | name - 2 | 0 | NULL | zee.mp4 |
+----+----------+----------------+----------+------------+--------------+-----------+
OUTPUTS:
In above my two tables my output should come following criterias
If I search by name LIKE '%name%' output should be
+----+----------+----------------+----------+------------+--------------+
| id | user_id | content_type | name | is_episode | episode_name |
+----+----------+----------------+----------+------------+--------------+
| 1 | 10 | 1 | name - 1 | 0 | NULL |
| 2 | 12 | 2 | name - 2 | 0 | NULL |
+----+----------+----------------+----------+------------+--------------+
If I search by name LIKE '%cname%' or name LIKE '%name - 2%' or name LIKE '%child%' output should be
+----+----------+----------------+----------+------------+--------------+
| id | user_id | content_type | name | is_episode | episode_name |
+----+----------+----------------+----------+------------+--------------+
| 2 | 12 | 2 | name - 2 | 0 | NULL |
+----+----------+----------------+----------+------------+--------------+
If I search by name LIKE '%name - 1%' output should be
+----+----------+----------------+----------+------------+--------------+
| id | user_id | content_type | name | is_episode | episode_name |
+----+----------+----------------+----------+------------+--------------+
| 1 | 10 | 1 | name - 1 | 0 | NULL |
+----+----------+----------------+----------+------------+--------------+
If I search by name LIKE '%child%' output should be
+----+----------+----------------+----------+------------+--------------+
| id | user_id | content_type | name | is_episode | episode_name |
+----+----------+----------------+----------+------------+--------------+
| 2 | 12 | 2 | name - 2 | 0 | NULL |
+----+----------+----------------+----------+------------+--------------+
I am unable to get proper output of my query. Could you plese write down query which is satisfied my all the output.
Your problem is that you're filtering out only rows that has Is_episode = 0 however you need to search in the rows that has is_episode = 1 like cname-2 and child-2
your problem caused because is_episode = 0, remove it and it should work. please leave a comment if you still have a problem.
Update: based in your comments, based on my understanding I think you may require some sort of multiple queries and separation based on the table or your logic/conditions then union results together.
select .. from parent, child .. where is_episode = 0 and name like ...
union
select .. from child join parent where episode_name like ...

How create new columns according the groups in a table?

By using mysql can i create new columns according the groups in a table?i only can get the grouping and group_concat.
Before
-------------------------
no | item | code |
-------------------------
1 | aa | x |
2 | cc | c |
3 | pfr | a |
4 | bog | |
5 | aa | x |
6 | pfr | x |
1 | aa | x |
6 | pfr | a |
-------------------------
After group and group_concat
-------------------------
no | item | code |
-------------------------
1 | aa | x-2 |
2 | cc | c-1 |
3 | pfr | a-1 |
4 | bog | |
5 | aa | x-1 |
6 | pfr | a-1,x-1 |
-------------------------
I want to make like below this. Is it possible?
-------------------------------------------------------------------------------------
no | aa_qty | aa_code | cc_qty | cc_code | pfr_qty | pfr_code | bog_qty | bog_code |
-------------------------------------------------------------------------------------
1 | 2 | x-2 | | | | | | |
2 | | | 1 | c-1 | | | | |
3 | | | | | 1 | a-1 | | |
4 | | | | | | | 1 | |
5 | 1 | x-1 | | | | | | |
6 | | | | | 2 | a-1,x-1 | | |
-------------------------------------------------------------------------------------
You can achieve this using Pivot Table mechanism. MySQL does not have direct support on this mechanism. You need to depend on various if .. else.. or case .. when ... statements to build the required result view.
On the sample data given, say in table item_codes with no, item, and code as columns, you can try following example.
select no,
case item when 'aa' then cnt else '' end as aa_qty,
case item when 'aa' then code else '' end as aa_code,
case item when 'cc' then cnt else '' end as cc_qty,
case item when 'cc' then code else '' end as cc_code,
case item when 'pfr' then cnt else '' end as pfr_qty,
case item when 'pfr' then code else '' end as pfr_code,
case item when 'bog' then cnt else '' end as bog_qty,
case item when 'bog' then code else '' end as bog_code
from
(
select no, item, sum(cnt) cnt, group_concat( code ) code
from
(
select
no, item, count(no) cnt,
if( code='', code, concat( code, '-', count(no) ) ) 'code'
from item_codes ic
group by ic.no, ic.item, ic.code
) ig group by no, item
) grouped_data;
You may require some changes based on the data differences and other occurrences like null and empty codes, etc.