Replace value with related value - php

I have a table which shows the details of galleries, each entry has a Gallery_ID, one of the fields is gallery_parent which is 0 if the record has no parent and then number of its parent if it does.
ID| Name | parent
1 | gallery A | 0
2 | gallery B | 0
3 | gallery C | 0
4 | gallery D | 1
5 | gallery E | 2
How can I replace the parent gallery number with the parent gallery name?

you need two join the table to itself using LEFT JOIN
SELECT a.ID,
a.Name,
b.Name as ParentName //-- you can apply COALESCE here
FROM tableName a
LEFT JOIN tableName b
ON a.parent = b.id
SQLFiddle Demo
SQLFiddle Demo (with COALESCE)

Above answer shows how to select the data and if you do want to update and if the parent is a varchar, you can do the following
UPDATE gal t1
LEFT JOIN gal t2 ON t1.parent=t2.ID
SET t1.parent = t2.name

Related

a complex sql query with outer join

there are two tables
a
------------------------------
id | Name
------------------------------
1 | Alpha
-----------------------------
2 | Beta
-----------------------------
3 | Gamma
-----------------------------
4 | Delta
-----------------------------
and another table b with foreign key of table a
b
-----------------------------
id | a_id | Film
-----------------------------
1 | 1 | Bladerunner
-----------------------------
2 | 1 | Star Wars
-----------------------------
3 | 3 | Superman
-----------------------------
4 | 4 | Rollerball
-----------------------------
Write an SQL query using outer join to get all names from table ā€œaā€ that don't have a film starting with ā€œSā€.
Query result should be:
Beta
--------
Delta
Use correlated subquery with not exists
DEMO
SELECT *
FROM tablea a
LEFT JOIN tableb b
ON a.id = b.a_id
WHERE NOT EXISTS (SELECT 1
FROM tableb b1
WHERE b.a_id = b1.a_id
AND film LIKE 'S%')
OR you can use below query to avoid subquery
SELECT NAME,
Sum(CASE
WHEN film LIKE 'S%' THEN 1
ELSE 0
END)
FROM t1 a
LEFT JOIN t2 b
ON a.id = b.a_id
GROUP BY NAME
HAVING Sum(CASE
WHEN film LIKE 'S%' THEN 1
ELSE 0
END) = 0
OUTPUT:
name
Delta
Beta
SELECT a.NAME
FROM a
LEFT JOIN b
ON a.id = b.a_id
WHERE a.NAME NOT IN (SELECT a.NAME
FROM a
LEFT JOIN b
ON a.id = b.a_id
WHERE b.film LIKE 's%')
GROUP BY a.NAME
output
Beta
Delta
according to the OPs question which he has not mentioned and just gave output part in his question... he wants all the name of the table a where film name do not start with letter S from table b. the above query fullfilled the requirements of OPs completely and in most standard way.
OP just mentioned the join in the question but he do not mentioned that he want those id name also which do not exist in table b in a_id i.e the output part beta.
use substring and join
select a.name from t1 a left join
t2 b on a.id=b.a_id
where a.id not in ( select b.a_id from t2 b
where
upper(substring(b.Film,1,1)) like '%S%' and b.a_id is not null
)
output
name
Delta
Beta
demo link

MySQL Join three tables and display 0 if null

I have three tables:
person_table
id| name | gender
1 | Joe | male
2 | Jane |female
3 | Janet | female
4| Jay | male
etc...
product_table
id| name
1 | magazine
2 | book
3 |paper
4 | novel
etc...
**person_product
person_id| product_id | quantity
1 | 1 | 1
1 | 3 | 3
2 | 3 | 1
4 | 4 | 2
etc...
I have tried to make a query that will return a table like this:
person_id| person_name | product_name| quantity
but i can't make it so that if lets say John has no books, it should display
(johns id) John|book|0
instead of just skipping this line.
Where did i go wrong?
here is what i managed to come up with:
SELECT p.*, f.name, l.quantity
FROM person_product AS l
INNER JOIN people_table AS p ON l.person_id=p.id
INNER JOIN product_table AS f ON l.product_id=f.id
ORDER BY id`
It seems that you're generating a report of all people, against all products with the relevant quantity; on a large data set this could take a while as you're not specifically joining product to person for anything other than quantity:
SELECT
p.id,
p.name,
p.gender,
f.name,
IFNULL(l.quantity,0) AS quantity
FROM person_table AS p
JOIN product_table AS f
LEFT JOIN person_product AS l
ON l.person_id = p.id
AND l.product_id = f.id
ORDER BY p.id, f.name
Which results in:
Is that more-or-less what you're after?
you need to start with people_table than using left join you need to bring other table data.
as you need 0 value if null than you can use function IFNULL
SELECT p.*, f.name, IFNULL(l.quantity,0)
FROM people_table AS p
LEFT JOIN person_product AS l ON l.person_id=p.id
LEFT JOIN product_table AS f ON l.product_id=f.id
ORDER BY p.id
if has no book shouldn't appear in the table , try this (easy to understand) :
SELECT NAME
,'0'
,'0'
FROM person_table
WHERE id NOT IN (
SELECT person_id
FROM person_product
)
UNION
SELECT person_id
,product_id
,quantity
FROM person_product;

Mysql query inside a query

First, apologies if the title doesn't match the question. Well, the problem is how to build this query...
I have a table called category It contains categories of my stuff(movies). It's like this...
--------------------------------
ID | name | parent_category
--------------------------------
1 | love | 0
2 | action | 0
3 | fear | 0
4 | passion| 1
5 | danger | 2
6 | death | 3
--------------------------------
So, as you see, each category has a parent category. Except the first 3. They're parents.
And movies table is like this...
--------------------------------
ID | name | category
--------------------------------
1 | aaaa | 1
2 | bbbbbb | 2
3 | cccc | 2
4 | ddddddd| 1
5 | eeeeee | 3
6 | fffff | 3
--------------------------------
So, what i want to do is, to select movies by parent category. Which means if I click category, love, it should select all the movies of categories that having love as the parent category.
So, how to write this in a single query ?
If the parents are only one level deep, then you can use joins:
select m.*,
coalesce(cp.id, c.id) as parent_id,
coalesce(cp.name, c.name) as parent_name
from movies m left join
categories c
on m.category = c.id left join
categories cp
on c.parent_category = cp.id;
Actually, if you only want the id, you don't need two joins:
select m.*,
(case when c.parent_id > 0 then c.parent_id else c.id end) as parent_id
from movies m left join
categories c
on m.category = c.id ;
Or, more simply:
select m.*, greatest(c.parent_id, c.id) as parent_id
. . .
to select rows filtered by condition on secend table use join in FROM clause or subquery in condition with IN or EXISTS function. To compare field with some string you can use LIKE operator.
If you are filtering based on parent_category -
SELECT b.*, a.name FROM movies b
LEFT JOIN categories a ON a.id = b.category
WHERE a.parent_category = 1;

How do I select all categories per product and returning this in one row per product?

I'm having a bit of a brain freeze now, because this should be very easy (I think).
I have three tables:
products list
categories list
category_map (links product and category)
I want to list products with its categories (names). One product may have many categories.
// This query
SELECT a.id, a.name, b.category
FROM sl_link_product_category c
LEFT JOIN sl_product a ON c.fk_productID = a.id
LEFT JOIN sl_category b ON c.fk_categoryID = b.id
WHERE c.fk_categoryID = b.id
ORDER BY a.id
// Gives me this result
| 1 | product 1 | cat 1 |
| 1 | product 1 | cat 2 |
| 1 | product 1 | cat 3 |
| 2 | product 2 | cat 2 |
| 2 | product 2 | cat 4 |
Now, in the final result set, I want an array with products where each product has an array of categories.
My question is; Do I have to work with the result set in PHP to achieve my goal? Or is it possible in MySQL to put all categories (comma separated) in one variable / column?
The GROUP_CONCAT function is what you're looking for:
SELECT a.id, a.name, GROUP_CONCAT(b.category)
FROM sl_link_product_category c
LEFT JOIN sl_product a ON c.fk_productID = a.id
LEFT JOIN sl_category b ON c.fk_categoryID = b.id
GROUP BY a.id, a.name
ORDER BY a.id

Mysql subquery how can i get only all records from Table1 and if no match found with Table2 still list them as null or something else?

1) I have two table:
+------ +---------
topic mytask
+--------- +---------
ID | What ID | TopicID
---------- ------------
1 | A 1 | 1
2 | B
2) I have SQL as below:
SELECT
a.id, b.id
FROM
topic a
JOIN (
SELECT
b.id,b.topicid
FROM
mytask b
) b on (b.topicid=a.id)
3) I have output as below (1 ROW ONLY):
ID | ID
-------
1 | 1
My expected output is as below (2 ROW, PRIORITY TO TOPIC BY LISTING THEM ALL) :
a.ID | b.ID
-------------
1 | MATCHED - OK - TAKE IT!!!
2 | NULL or what,ever...
How can i do that?
Use a left outer join:
SELECT
a.id, b.id
FROM
topic a
LEFT JOIN (
SELECT
b.id,b.topicid
FROM
mytask b
) b on (b.topicid=a.id)
and simplify the query to
SELECT
a.id, b.id
FROM
topic a
LEFT JOIN
mytask b ON b.topicid = a.id

Categories