I have multiple tables as follows:
TABLE 1: Product
+-----+----------+--------+---------------------+
| id | biz_id | name | message |
+-----+----------+--------+---------------------+
| 1 | 1 | test1 | One tow three |
| 2 | 1 | test1 | One tow three |
| 3 | 1 | test1 | One tow three |
| 4 | 2 | test2 | hello world |
| 5 | 2 | test2 | hello world |
+-----+----------+--------+---------------------+
TABLE 2: Images
+-----+----------+--------------+-------------------+
| id | biz_id | product_id | path |
+-----+----------+--------------+-------------------+
| 1 | 1 | 1 | img/qwert1.jpg |
| 2 | 1 | 2 | img/qwert2.jpg |
| 3 | 1 | 3 | img/qwert3.jpg |
| 4 | 2 | 4 | img/qwery4.jpg |
| 5 | 2 | 5 | img/qwert5.jpg |
+-----+----------+--------------+-------------------+
How can I avoid duplicate in mysql while joining multiple tables?
My Query is Join both tables such that I want to avoid duplicate product(Get Distint product by name) and get all images associated with that product(Eg. Product>name - test1 has images qwert1.jpg, qwert2.jpg, qwert2.jpg )
SELECT p.name, GROUP_CONCAT(i.path)
FROM product AS p
INNER JOIN images AS i ON p.id = i.product_id
GROUP BY p.name;
Please note that this is not standard SQL, but most DBMS offer this functionality (although the keyword may be a bit different).
simple join should do all things
select p.name as Name, i.message as IMG from Images
left join Product p
on i.biz_id=p.biz_id
group by p.name;
use left join with GROUP_CONCAT or group by
select p.name name,GROUP_CONCAT(i.path) img
from Images i left join Product p
on i.biz_id=p.biz_id
group by i.product_id
I am trying to figure out how to select an item from table by his column name p.e.
strucutre looks like this
table items
id | name | column_1 | column_2 | column_3 |
1 | nm1 | 1 | 4 | 7,8 |
2 | nm2 | 2,3 | 4 | 9 |
3 | nm3 | 3,1 | 4 | 7 |
table columns
id | c_name |
1 | cnm1 |
2 | cnm2 |
3 | cnm3 |
table column_values
id | c_id | value |
1 | 1 | abcd |
2 | 1 | cdbh |
3 | 1 | dsff |
4 | 2 | wewe |
5 | 2 | cgbh |
6 | 2 | cdlh |
7 | 3 | adbh |
8 | 3 | qdbh |
9 | 3 | pdbh |
So when I wanted to find "abcd" I tried
"SELECT a.* FROM items a, columns b, column_values c WHERE c.`value` LIKE '%abcd%' GROUP BY a.`id`"
but I knew this will find nothing without any conections so i went further
"SELECT a.* FROM items a, columns b, column_values c WHERE c.`value` LIKE '%abcd%' AND b.`id` = c.`c_id` GROUP BY a.`id`"
still no proper connection with item
and here is the problem there is a changing amount of columns and the name contains id of the column and value is set of ids of column values.
So i need to select item by his name which is "name+"column_id in column_values by FIND IN SET cause if i look for abcd it is id 1 and there are two items which have id 1 in column_1
item 1 and item 2
ALSO id of values are AI so there is not possibility of duplicate so there is no need to check of column_id to search in proper column in item table
it can work something like for from 0 - 30 p.e. and it will search in column_1, column_2 column_3 until 30 for id match
here is my table:
-------------------------
A1 | A2 | count |
-------------------------
a | b | 1 |
b | a | 1 |
c | a | 1 |
d | b | 1 |
b | d | 1 |
-------------------------
i want to select distinct values from this table with distinct count values.If i use to select A2 column where clause i specified using "b" that time i want result like this
A | count
--------------
a | 1
d | 1
I guess this is what you need ,
select distinct(A2) from table1 where count=1
so that you get this output ,
A | count
--------------
a | 1
d | 1
Are you trying to do this:
select A1 as A,count FROM Table1 WHERE A2 = 'b' GROUP BY A1,count
It will give you the result:
A count
a 1
d 1
See SQL Fiddle
I have table structure like below:
id |parent|name |value
1 | 0 | aaa |
2 | 0 | bbb |
3 | 0 | ccc |
4 | 1 | | 111
5 | 1 | | 222
6 | 3 | | 333
I want to display parent if it has child records.
Like:
(parent id + name + value first child)
1 - aaa - 111
3 - ccc - 333
There is no meaning of the first child in the database, you can get the first child by the mininum of the id or the minimum of the value, but the values are not stored with a specific order in the table, so you can't tell which value is the first one.
But, assuming that the id is auto incremental column, then value of the first child is the value of the minimum id, then you can do this:
SELECT
t1.parent,
t2.name,
t1.value
FROM tablename AS t1
INNER JOIN
(
SELECT MIN(id) AS id, parent
FROM tablename
GROUP BY parent
) AS t22 ON t22.id = t1.id AND t1.parent = t22.parent
INNER JOIN tablename AS t2 ON t1.parent = t2.id;
See it in action here:
SQL Fiddle Demo
This will give you :
| PARENT | NAME | VALUE |
-------------------------
| 1 | aaa | 111 |
| 3 | ccc | 333 |
Or: You can get it by the minimum value:
SELECT
t1.parent,
t2.name,
MIN(t1.value) AS value
FROM tablename AS t1
INNER JOIN tablename AS t2 ON t1.parent = t2.id
GROUP BY t1.parent, t2.name;
See it in action:
SQL Fiddle Demo
This will give you:
| PARENT | NAME | VALUE |
-------------------------
| 1 | aaa | 111 |
| 3 | ccc | 333 |
My previous problem and solution:
Get max and min from fields
This working OK, but i would like skip 0 and NULL in this examples.
For example:
First:
id | title
1 | aaa
2 | bbb
3 | ccc
Second:
id | first_id | one | two | three | four
1 | 1 | 3 | 0 | 4 | 6
2 | 2 | 4 | 4 | 1 | 2
3 | 3 | 1 | NULL | 3 | 4
this should show me:
id | title | min | max
1 | aaa | 3 | 6
2 | bbb | 1 | 4
3 | ccc | 1 | 4
and not:
id | title | min | max
1 | aaa | 0 | 6
2 | bbb | 1 | 4
3 | ccc | 0 | 4
In which example from my previous question is the best way to implement skip 0 and NULL?
Pop these into your clause
SELECT
f.id,
f.title
MIN(LEAST(greatest(coalesce(s.one,0),1), greatest(coalesce(s.two,0),1), greatest(coalesce(s.three,0),1), greatest(coalesce(s.four,0),1))) as min,
MAX(GREATEST(greatest(coalesce(s.one,0),1), greatest(coalesce(s.two,0),1), greatest(coalesce(s.three,0),1), greatest(coalesce(s.four,0),1))) as max
FROM
First f
INNER JOIN Second s
on f.id = s.first_id
GROUP BY
f.id,
f.title
You can use coalesce(fieldName, 1) to turn a null into a 1.
Again, as said in your previous question, this is HORRIBLE use of a query to force an answer. You should be changing the layout of the database.
Edit: I have nutted out the data you want, but before you look at it, be aware that if one of my colleagues wrote a script like this, he would be sacked on the spot. This is HIDEOUS and should NOT BE USED.
select
f.id,
f.title,
(select min(z.myVal) from
(
select
b.id,
b.first_id,
b.one as myVal
from
second b
where
b.one is not null
and b.one > 0
union
select
b.id,
b.first_id,
b.two as myVal
from
second b
where
b.two is not null
and b.two > 0
union
select
b.id,
b.first_id,
b.three as myVal
from
second b
where
b.three is not null
and b.three > 0
union
select
b.id,
b.first_id,
b.four as myVal
from
second b
where
b.four is not null
and b.four > 0
) z
where
f.id=z.first_id) as miniVal,
greatest(
coalesce(s.one,0),
coalesce(s.two,0),
coalesce(s.three,0),
coalesce(s.four,0)
) as maxiVal
from
first f,
second s
where
f.id=s.first_id
output Data
+------+-------+---------+---------+
| id | title | miniVal | maxiVal |
+------+-------+---------+---------+
| 1 | aaaa | 3 | 6 |
| 2 | bbbb | 1 | 4 |
| 3 | cccc | 1 | 4 |
+------+-------+---------+---------+
3 rows in set (0.00 sec)
Running this query made me throw up a little in my mouth. That's how wrong it is to write SQL like this.
While seemingly clunky, this solution should work:
SELECT
a.id, a.title, MIN(b.num) AS min, MAX(b.num) AS max
FROM
first a
LEFT JOIN
(
SELECT first_id, one AS num FROM second UNION ALL
SELECT first_id, two FROM second UNION ALL
SELECT first_id, three FROM second UNION ALL
SELECT first_id, four FROM second
) b ON
a.id = b.first_id AND
b.num IS NOT NULL AND
b.num > 0
GROUP BY
a.id, a.title
What this does is it actually gets each number column into its own row, but only the numbers that are not null and > 0. Before the GROUP BY, the result of the LEFT JOIN would look something like:
id | title | num
---------------------
1 | aaa | 3
1 | aaa | 4
1 | aaa | 6
2 | bbb | 1
2 | bbb | 2
2 | bbb | 4
2 | bbb | 4
3 | ccc | 1
3 | ccc | 3
3 | ccc | 4
Then by the groupings of each first (GROUP BY a.id, a.title), we can use the MIN() and MAX() aggregate functions on the num column to extract minimum and maximum values per first group:
id | title | min | max
----------------------------
1 | aaa | 3 | 6
2 | bbb | 1 | 4
3 | ccc | 1 | 4
In the case that a first_id had all four columns having NULL's or 0's, the min and max values would show up as NULL due to using a LEFT JOIN instead of an INNER JOIN as I believe this is would be a better behavior for your situation:
id | title | min | max
----------------------------
4 | ddd | NULL | NULL
USE:
WHERE COLUMN IS NOT NULL AND COLUMN <> 0;
I think you just need to nest the LEAST expressions:
LEAST(
NULLIF(one,0),
LEAST(
NULLIF(two,0),
LEAST(
NULLIF(three,0),
LEAST(
NULLIF(four,0),
null ))))
Edit I just looked it up. The LEAST function takes multiple arguments:
LEAST( NULLIF(one,0), NULLIF(two,0), NULLIF(three,0), NULLIF(four,0))
Edit 2 I see you want both min and max. Obviously you'd just change LEAST to GREATEST or MIN to MAX as needed.
This may be more straightforward or you may not have a handy least function.
SELECT
f.id, f.title,
(
SELECT MIN(NULLIF(val, 0))
FROM
(
SELECT one AS val UNION ALL
SELECT two UNION ALL
SELECT three UNION ALL
SELECT four
) AS vals
)
) as minval
FROM First f INNER JOIN Second s on f.id = s.first_id
You haven't specified if it's possible for all four columns to be null/0. We may need to tweak for that case.
You can use IFNULL():
WHERE IFNULL(fieldname, 0) != 0