How to select distinct values from multiple columns using mysql php - php

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

Related

How to select similar values together in same query?

I have the database as below, i need to get all the zeros and ones in separate list from the below table, that is to get all the zero together in a column and all the ones together in separate column
database
| id | value |
-------------
| 1 | 0 |
| 2 | 1 |
| 3 | 0 |
| 4 | 1 |
expected result
| sp.id | stop | st.id | start|
-------------------------------
| 1 | 0 | 2 | 1 |
| 3 | 0 | 4 | 1 |
or
| id | value |
-------------
| 1 | 0 |
| 3 | 0 |
| id | value |
-------------
| 2 | 1 |
| 4 | 1 |
SELECT a.id AS sp.id, a.value AS stop, b.id AS st.id, b.value AS start
FROM (SELECT * FROM TABLE WHERE = 0) a
LEFT JOIN (SELECT * FROM TABLE WHERE = 1) b
ON a.id = b.id
UNION
SELECT a.id AS sp.id, a.value AS stop, b.id AS st.id, b.value AS start
FROM (SELECT * FROM TABLE WHERE = 0) a
RIGHT JOIN (SELECT * FROM TABLE WHERE = 1) b
ON a.id = b.id
For your expected result 1, you can use case
select case when value=0 then id end as spid,
case when value=0 then value end as stop,
case when value=1 then id end as stid,
case when value=1 then value end as start
from yourtable.
But you will get NULL for empty rows as shown below. If that is fine, you can use the above query. If it is a String you can use MAX() or MIN() with group by to avoid this empty values.
OUTPUT
+------+------+------+-------+
| spid | stop | stid | start |
+------+------+------+-------+
| 1 | 0 | | |
+------+------+------+-------+
| | | 2 | 1 |
+------+------+------+-------+
| 3 | 0 | | |
+------+------+------+-------+
| | | 4 | 1 |
+------+------+------+-------+
For you expected output 2, you can directly use UNION ALL
select id,value from test where value=0
union all
select id,value from test where value=1
OUTPUT
+----+-------+
| id | value |
+----+-------+
| 1 | 0 |
+----+-------+
| 3 | 0 |
+----+-------+
| 2 | 1 |
+----+-------+
| 4 | 1 |
+----+-------+
CHECK DEMO HERE

SQL select statement column order with union

Is there a way in union tables to ignore first select column order and to match records by column names?
Take for example this:
// TEST1 table:
| a | b |
-------------
| 3 | 5 |
// TEST2 table:
| b | a |
-------------
| 4 | 9 |
select a, b from TEST1 union ( select b, a from TEST2)
// The result must be a table like the on below:
| a | b |
-------------
| 3 | 5 |
-------------
| 9 | 4 |
// BUT, actually is:
| a | b |
-------------
| 3 | 5 |
-------------
| 4 | 9 |
UPDATE:
The name of the columns and their numbers are the same, just the order is different and I CAN'T change the second select column order.
I'm asking for a way to ignore the default sql union behavior and to tell it to match the column name, not the order of passing
UNION doesn't have this kind of fonctionnality.
You have to find a workaround for instance :
select concat('a',a) as a, concat('b',b) as b from TEST1 union ( select concat('b',b) as b, concat('a',a) as a from TEST2)
You will have something like that :
| a | b |
-------------
| a3 | b5 |
-------------
| b4 | a9 |
Then you can parse it and reorder it programmatically.
The order of the fields in the table is irrelevant. It's the order that you specify the fields in your union's sub-queries that counts.
Currently you have:
select a, b from TEST1
union | |
select b, a from TEST2)
when it should be
select a, b from TEST1
union | |
select a, b from TEST2
The ONLY time that field-ordering in the table definition would matter is if you were doing select *.

DISTINCT values for two columns in MySQL

I have a table with contents like the following:
+----+-----------+---------+--------+------+
| id | text_from | text_to | text | seen |
+----+-----------+---------+--------+------+
| 1 | A | B | Hello1 | 0 |
| 2 | X | Y | Hello2 | 1 |
| 3 | Y | X | Hello3 | 1 |
| 4 | B | A | Hello4 | 1 |
+----+-----------+---------+--------+------+
It is a conversation like A sends a text to B, B sends to A etc. How can I get the DISTINCT conversation? For example, distinct conversation between A and B, or X and Y etc.
I want to get something like
+----+-----------+---------+--------+------+
| id | text_from | text_to | text | seen |
+----+-----------+---------+--------+------+
| 1 | A | B | Hello1 | 0 |
| 2 | X | Y | Hello2 | 1 |
+----+-----------+---------+--------+------+
If once text_from and text_to has two unique values, it can not be repeated. For example, if there is text_from = A, text_to = B, the table should not have text_from = B, text_to = A.
I am trying several methods for DISTINCT and GROUP BY since a few hours, but could not figure out any solution! Any suggestions would be greatly appreciated.
Seems like a simple NOT EXISTS should do the trick. Example SQL Fiddle
select *
from table t
where not exists (
select 1
from table t1
where
(
(t.text_from = t1.text_from
and t.text_to = t1.text_to)
or (t.text_from = t1.text_to
and t.text_to = t1.text_from)
) and t.id > t1.id
)

Parent / Child in same table

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 |

Count the frequency of votes in MySQL

I am making a website where users can vote on which category a page is. They can vote that the page is in category a, b, c, or d.
I need to find the most commonly occurring category in the MySQL row out of all the votes.
Each time a user submits their vote, it submits the "category" that they voted for, and the "page_id".
I have this so far:
SELECT page_id, category
FROM categories
GROUP BY page_id
I cannot use a COUNT(*) WHERE category = 'a' then repeat it for each category because there is many more categories in the actual project.
If your table looks something like this:
SELECT * from categories;
+---------+----------+
| page_id | category |
+---------+----------+
| 1 | a |
| 1 | b |
| 1 | a |
| 1 | c |
| 1 | a |
| 1 | b |
| 1 | a |
| 2 | d |
| 2 | d |
| 2 | c |
| 2 | d |
| 3 | a |
| 3 | b |
| 3 | c |
| 4 | c |
| 4 | d |
| 4 | c |
+---------+----------+
17 rows in set (0.00 sec)
Then you may want to try this query:
SELECT c1.page_id, MAX(freq.total),
(
SELECT c2.category
FROM categories c2
WHERE c2.page_id = c1.page_id
GROUP BY c2.category
HAVING COUNT(*) = MAX(freq.total)
LIMIT 1
) AS category
FROM categories c1
JOIN (
SELECT page_id, category, count(*) total
FROM categories
GROUP BY page_id, category
) freq ON (freq.page_id = c1.page_id)
GROUP BY c1.page_id;
Which returns this:
+---------+-----------------+----------+
| page_id | MAX(freq.total) | category |
+---------+-----------------+----------+
| 1 | 4 | a |
| 2 | 3 | d |
| 3 | 1 | a |
| 4 | 2 | c |
+---------+-----------------+----------+
4 rows in set (0.00 sec)
Compare the results with the actual frequency distribution:
SELECT page_id, category, COUNT(*) FROM categories GROUP BY page_id, category;
+---------+----------+----------+
| page_id | category | COUNT(*) |
+---------+----------+----------+
| 1 | a | 4 |
| 1 | b | 2 |
| 1 | c | 1 |
| 2 | c | 1 |
| 2 | d | 3 |
| 3 | a | 1 |
| 3 | b | 1 |
| 3 | c | 1 |
| 4 | c | 2 |
| 4 | d | 1 |
+---------+----------+----------+
10 rows in set (0.00 sec)
Note that for page_id = 3, there is no leading frequency, in which case this query makes no guarantee on which category will be chosen in such a case.
something like
SELECT category, page_id, count(vote_id)
FROM categories
WHERE category in ('a', 'b', 'c', 'd')
GROUP BY category, page_id
ORDER BY count(vote_id) DESC
LIMIT 1
should do the trick. I assume here the votes are individually stored in a separate row per vote.
It only looks in the cqtegory you're interested in, sorts with the most votes first and only returns the first one.

Categories