how can I count mysql data with group by - php

I have a php web page and I got a problem with counting data using group by in mysql query
When any question submitted, id is automatically add and idqu=0
if question replied then idqu is equal to replied question's id
My table and data
id idqu question answer user date
1 0 quest1 test 28042014
2 0 quest2 scott 29042014
3 2 reply1 andy 01052014
4 0 quest3 test 01052014
5 4 reply2 scot 01052014
My question is how can I count question's reply?
quest1 (0)
quest2 (1)
quest3 (1)

This query does the job. I gave the table the name "tbl"
Select q.id, count(a.id) as answers
From tbl q
Left join tbl a on a.idqu=q.id
Where q.idqu=0
Group by q.id

Try this
Select t1.question, count(t2.id) as counts
From table1 t1
Left join table1 t2 on t2.idqu=t1.id
Where t1.idqu=0
Group by t1.id
DEMO

select idqu, count(idqu) as reply_count
from table_name
where idqu <> 0
group by idqu

This is for every replies, with a bit of php. You don't need group by I think.
$query="SELECT * From YourTable WHERE idqu>0";
$res=mysql_query($query);
mysql_num_rows($res);
If you want to select replies on one question, add an AND idqu=(yourInt) in the query.
Hope I did understand and replied correctly!

If I understand correctly, try:
SELECT question, SUM(CASE WHEN idqu > 0 THEN 1 ELSE 0 END)
FROM tablename
GROUP BY question

Related

MySQL: Search for coincidences and differences in two tables

I need to find matchs between two tables, but also need to display when there is no match.
Table1: id, dni_number, name, business_id
Table2: id, dni, business_id
I need to form a table like this:
id
dni
name
business_id
is_match
1
12365478
John Doe
15451
1
1
22365478
Karen Doe
23451
0
is_match meaning 1: it found the dni in table1 and also in table2, 0 for not match
The query should have a where condition to find matchs from certain business_id
Any help will be much appreciated. Thanks in advance
SELECT
tblA.id,
1 as is_match
FROM tblA, tblB
WHERE tblA.id = tblB.id
UNION ALL
SELECT
tblA.id,
0 as is_match
FROM tblA, tblB
WHERE tblA.id != tblB.id
SELECT *, (table2.dnu = table1.dnu) AS is_match
FROM table1
LEFT JOIN table2 ON table1.business_id = table2.business_id
WHERE table1.business_id = xxx;

Get data if insert are in the same second

I have this table :
id idm date_play
1 5 2017-08-23 12:12:12
2 5 2017-08-23 12:12:12
3 6 2017-08-23 12:14:13
I want to identify if user has more then one insert in the same second. In the case describe I want to get the user id that is 5.
I tried like this :
SELECT `idm`, MAX(`s`) `conseq` FROM
(
SELECT
#s := IF(#u = `idm` AND (UNIX_TIMESTAMP(`date_play`) - #pt) BETWEEN 1 AND 100000, #s + 1, 0) s,
#u := `idm` `idm`,
#pt := UNIX_TIMESTAMP(`date_play`) pt
FROM table
WHERE date_play >= '2017-08-23 00:00:00'
AND date_play <= '2017-08-23 23:59:59'
ORDER BY `date_play`
) AS t
GROUP BY `idm`
Can you help me please ? Thx in advance and sorry for my english.
Assuming your dates are accurate down to the second level, you can do this with a single aggregation:
select idm
from t
group by idm
having count(*) > count(distinct date_play);
If date_play has fractional seconds, then you would need to remove those (say by converting to a string).
If you want the play dates where there are duplicates:
select idm, date_play
from t
group by idm, date_play
having count(*) >= 2;
Or, for just the idms, you could use select distinct with group by:
select distinct idm
from t
group by idm, date_play
having count(*) >= 2;
(I only mention this because this is the only type of problem that I know of where using select distinct with group by makes sense.)
If you want all the rows that are duplicated, I would go for exists instead:
select t.*
from t
where exists (select 1
from t t2
where t2.idm = t.idm and t2.date_play = t.date_play and
t2.id <> t.id
);
This should have reasonable performance with an index on (idm, date_play, id).
If your table is called mytable, the following should work:
SELECT t.`idm`
FROM mytable t INNER JOIN mytable t2
ON t.`idm`=t2.`idm` AND t.`date_play`=t2.`date_play` AND t.`id`!=t2.`id`
GROUP BY t.`idm`
Basically we join the table with itself, pairing records that have the same idm and date_play, but not the same id. This will have the effect of matching up any two records with the same user and datetime. We then group results by user so you don't get the same user id listed multiple times.
Edit:
Gordon Linoff and tadman's suggestions led me to this probably much more efficient query (credit to them)
SELECT t.`idm`
FROM mytable t
GROUP BY t.`date_play`
HAVING COUNT(t.`id`)>1

Mysql query to count how many "1" or "2"s in the whole table?

I have a phpmyadmin console Running a voting database where users vote for person1 or person2. the entries then get put into a table with userID, and choiceID. user column is auto incrementing and choiceID is either 1 or 2 depending on what they voted for. this is all new to me and I am surprised I have made it this far. could anybody explain how to make a query that counts how many 1,s , and how many 2,s are inside my whole table at any given time? that would be very awesome.
SELECT choiceID, COUNT(userID) as number_of_votes FROM votes GROUP BY choiceID ORDER BY number_of_votes
Given a set of data like this:
Will result in this:
Here the SQL-Command. You just have to replace the tablename.
SELECT COUNT(*), choiceID FROM tablename GROUP BY choiceID;
You can use "CASE WHEN" clauses in your query:
SELECT
SUM( CASE WHEN choiceID = 1 THEN 1 ELSE 0 END ) AS choice_1,
SUM( CASE WHEN choiceID = 2 THEN 1 ELSE 0 END ) AS choice_2
FROM ...
WHERE ...
select count(*) from -tablename- where choiceID = '1'
or '2'...depending what you want :P

MySQL, check if result has value, if not take another [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a table structure like this:
Page_id || type || user_id
1 1 0
2 2 0
3 3 0
4 1 1
5 2 1
6 3 1
From this table I would like to get page_id 4,5 and 6.
But I can also have table data like this
Page_id || type || user_id
1 1 0
2 2 0
3 3 0
4 1 1
5 2 1
Then I would like to get page_id 4, 5 and 3.
So I have to get all the types, but with the priority user_id and if there is no record with user_id 1, then take the one with 0
Have tried a lot. I know I can sort it with PHP, but I hope there is a way with MySQL.
Regards Andreas
//////// ANSWER /////////
I got a lot of suggestions, and I haven't tried them all, so I can't tell it they where right or not. But I have accepted an answer, which worked for me.Thank to everybody.
SELECT a.Type, a.Page_ID
FROM table a
INNER JOIN
(SELECT Type, MAX(User_ID) AS User_ID
FROM table
GROUP BY Type ) b
ON a.Type = b.Type AND a.User_ID = b.User_ID
You can execute a SELECT query as follow
SELECT Page_id
FROM table
WHERE user_id != 0
This SQL Fiddle demonstrates the below query:
SELECT DISTINCT
(
SELECT s1.Page_id
FROM myTable AS s1
WHERE m.type = s1.type
ORDER BY s1.Page_id
LIMIT 1
) AS PageID, type,
(
SELECT s2.user_id
FROM myTable AS s2
WHERE m.type = s2.type
ORDER BY s2.Page_id
LIMIT 1
) AS User
FROM myTable AS m
The results are the records where Page_id is 1, 2, and 4. As you can see in both of the sub queries I am ordering by Page_id to make sure the data is pulled from the same record and the first Page_id for that occurrence of the type is selected.
To return only one record unique to a couple columns, you'll want to use the GROUP BY statement. Then for any other column outside of the group by columns, you need to pick an aggregate function so it knows how to summarize the value if it finds multiple records in that group. In this case you want non-zero, so max() would work
SELECT type, max(user_id) as user_id
FROM table
GROUP BY type
how about that?
select page_id,type from (
select page_id,type, user_id from mytable
group by page_id,type, user_id having user_id=max(user_id)
) as x where user_id=1
Will there ever be multiple rows for a page where user_id is not zero? Because if not (if at most you only have one row per page where user_id = 1) then this will work:
SELECT ifNull(t1.page_id,t2.page_id) as page_id, t1.type,
CASE WHEN t2.page_id IS NULL THEN t1.user_id ELSE t2.user_id END as user_id
#start with all rows (including duplicates)
FROM myTable t1
#look for a user_id > 0 for this type
LEFT OUTER JOIN myTable t2 ON t1.type = t2.type AND t2.user_id > 0
WHERE t2.page_id IS NULL # if no record with user_id > 0 found, then no need to filter
# if a record with user_id > 0 was found, then filer out the user_id = 0 record
OR (t2.page_id IS NOT NULL AND t1.user_id > 0)
See in SQLFiddle: http://sqlfiddle.com/#!2/ba877/5

Select Query with MAX

i've got a big Problem and i was trying the whole day and did not find any Solution. Hope you can help me?
I have two tables:
The first one named "orders":
orders_id | orders_date | .....
1 xxxxxxxxxx
2 xxxxxxxxxx
3 xxxxxxxxxx
The second is "orders_history":
orders_id | order_status_id | date_added
1 1 2009-10-01
1 2 2010-01-01
2 1 2010-02-01
3 1 2010-02-01
So now i want to have all orders where order_status_id = '1'
I have tried with MAX, HAVING, GROUP BY, ... Subselects also, but i haven't found any solution. I know it's not very hard, but i'm finished...
Is it something like:
SELECT orders.*, orders_history.* FROM orders, orders_history WHERE orders_history.order_status_id <= '1'
But then i also get Order with order_id 1
Hope you can help. Thank you!
Sascha
To further clarify, the poster's 'orders_history' table keeps track of the state of all orders over time. The goal is a query that will find all orders that currently have an order status of 1. Order ID# 1 currently has a status of 2, so it should not be included in the results.
Assumably, order status goes up over time and never goes down, so that the order status and date_added will constantly increase.
This should do it for you:
SELECT *
FROM orders
, orders_history
WHERE orders.orders_id = orders_history.orders_id
AND orders.orders_id IN (
SELECT orders_id
FROM orders_history
GROUP BY orders_id
HAVING MAX(order_status_id) = 1
)
I'm not surprised you had trouble getting this to work - it's a very tricky type of query where you must 'GROUP BY' and find the MAX and also all the other corresponding values in the same row. This is a common request, and it often surprises people that it's actually quite difficult to express this in SQL. Here's one way to do it in MySQL:
SELECT T2.orders_id FROM (
SELECT orders_id, MAX(date_added) AS date_added
FROM orders_history
GROUP BY orders_id
) AS T1
JOIN orders_history T2
ON T1.orders_id = T2.orders_id AND T1.date_added = T2.date_added
GROUP BY T2.orders_id, T2.date_added
HAVING MAX(order_status_id) = 1
Here I am assuming that:
orders_id, date_added is not unique.
orders_id, date_added, order_status_id is unique.
If not the second assumption is not true, add DISTINCT after the first SELECT.
Here are the results I get for your test data:
2
3
You can join this to your orders table if you want to fetch extra information about each order.
Edited after discussion in comments (changed the where clause):
SELECT orders.*, orders_history.*
FROM orders INNER JOIN orders_history
ON orders.orders_id = orders_history.orders_id
WHERE orders.orders_id IN
(SELECT orders_id FROM orders_history
GROUP BY orders_id
HAVING MAX(order_status_id) = 1)
select o.*, oh.*
from orders o
inner join orders_history oh on oh.orders_id = o.orders_id
where oh_orders_status = 1
should do the trick. It's a while since I touched mysql though, so I don't know if your orders_status should be in quotes - I'd guess not if it is an int...

Categories