Mysql Covert rows to columns - mysql

I have a table with order numbers, first name, last name, question and answers. There are 5 questions asked to the user, each answer to a question generates 1 row of data, which produces 5 rows per user. I need a query that returns order number, first name, last name and the questions and answers converted to columns, returning 1 row per user.
Any help would be appreciated
Thanks,
Larry

Seems like you want to join the table to itself 5 times.
Something like
select q1.first_name, q1.last_name, max(q1.question), max(q1.answer), max(q2.question), max(q2.answer),max(q3.question), max(q3.answer),...
from questions q1
join questions q2 on q1.first_name=q2.first_name and q1.last_name=q2.last_name
join questions q3 on q1.first_name=q3.first_name and q1.last_name=q3.last_name
where q1.order_number = 1 and q2.order_number = 2 and q3.order_number = 3 ...
group by q1.first_name, q1.last_name
Using max will collapse down the rows into unique first name/last name pairs.

Related

Count and sum up all duplicate records in MySQL

I have table with, following structure.
id name
1 john
2 ana
3 john
4 ana
5 peter
6 ana
7 Abrar
8 Raju
Duplicate entries in the table are as follows
john(2) duplicate
ana(3) duplicate
The names which are duplicates are john and ana.
My question is how would I count the records in total which are duplicate here it is '5' records
Note : I also followed the similar question in community but it explains how we can add the number of duplicates exists for that particular name in the table and adds up the third column in table representing the duplicates records with same name but in my case I wanted to know the number of all duplicates exist in the table (here the result of the query is just number "5") irrespective of the names.
Just take a count subquery on the query you already have in mind (or perhaps have already written):
SELECT SUM(cnt) AS total_duplicates
FROM
(
SELECT COUNT(*) AS cnt
FROM yourTable
GROUP BY name
HAVING COUNT(*) > 1
) t;
Demo

Can I retrieve 2 different results from 1 table in a single query? [duplicate]

This question already has answers here:
Find total number of results in mySQL query with offset+limit
(7 answers)
Closed 6 years ago.
I am making a pagination function, here is my case:
1 table (example)
id | title | date | details
Now, I want to retrieve two different results from this table (example)
Count all of the rows (for the total count of all the lists)
I will only show every 10 list per page.
My current code is, I have 2 separated queries for 1 and 2, so it is like 2 connections, my question is, can this be done with a single query and then retrieve both of 1 and 2 results? If so, what do I need to do? Any suggestion/s can help me!
I think,
This will help you.
Step 1: Get the all list from the table
Step 2: Then count the records
Here is the single query to perform it.
SELECT COUNT(tmp.id) as cnt, tmp.* FROM (SELECT id, title, date, details FROM tablename) tmp

ORDER BY and GROUP BY those results in a single query

I am trying to query a dataset from a single table, which contains quiz answers/entries from multiple users. I want to pull out the highest scoring entry from each individual user.
My data looks like the following:
ID TP_ID quiz_id name num_questions correct incorrect percent created_at
1 10154312970149546 1 Joe 3 2 1 67 2015-09-20 22:47:10
2 10154312970149546 1 Joe 3 3 0 100 2015-09-21 20:15:20
3 125564674465289 1 Test User 3 1 2 33 2015-09-23 08:07:18
4 10153627558393996 1 Bob 3 3 0 100 2015-09-23 11:27:02
My query looks like the following:
SELECT * FROM `entries`
WHERE `TP_ID` IN('10153627558393996', '10154312970149546')
GROUP BY `TP_ID`
ORDER BY `correct` DESC
In my mind, what that should do is get the two users from the IN clause, order them by the number of correct answers and then group them together, so I should be left with the 2 highest scores from those two users.
In reality it's giving me two results, but the one from Joe gives me the lower of the two values (2), with Bob first with a score of 3. Swapping to ASC ordering keeps the scores the same but places Joe first.
So, how could I achieve what I need?
You're after the groupwise maximum, which can be obtained by joining the grouped results back to the table:
SELECT * FROM entries NATURAL JOIN (
SELECT TP_ID, MAX(correct) correct
FROM entries
WHERE TP_ID IN ('10153627558393996', '10154312970149546')
GROUP BY TP_ID
) t
Of course, if a user has multiple records with the maximal score, it will return all of them; should you only want some subset, you'll need to express the logic for determining which.
MySql is quite lax when it comes to group-by-clauses - but as a rule of thumb you should try to follow the rule that other DBMSs enforce:
In a group-by-query each column should either be part of the group-by-clause or contain a column-function.
For your query I would suggest:
SELECT `TP_ID`,`name`,max(`correct`) FROM `entries`
WHERE `TP_ID` IN('10153627558393996', '10154312970149546')
GROUP BY `TP_ID`,`name`
Since your table seems quite denormalized the group by name-par could be omitted, but it might be necessary in other cases.
ORDER BY is only used to specify in which order the results are returned but does nothing about what results are returned - so you need to apply the max()-function to get the highest number of right answers.

Sorting Counts in Access

I am using Access 2013 and I have many Yes/No fields in a table named Survey. I have 25 survey questions that people check if true (yes), and I am querying the fields across the whole database to get a count of how many people entered Yes for each field. A subset of my table is:
SurveyID AutoNumber
MemberID Number
Question1 Yes/No
Question2 Yes/No
Question3 Yes/No
etc...
The following query runs against the table above and is a subset of what I have, in that it only represents three fields:
SELECT Count(IIf([Survey]![Question1]=True,1,Null)) AS CountOfQuestion1, Count(IIf([Survey]![Question2]=True,1,Null)) AS CountOfQuestion2, Count(IIf([Survey]![Question3]=True,1,Null)) AS CountOfQuestion3
FROM Survey;
This works fine (the IIF bit is due to Access and its strangeness). My question is, how do I now order this? Each result comes out as a separate field in the query, and I need to order on the results of all the fields, not just one field. For example, I might get the following:
CountOfQuestion1 34
CountOfQuestion2 7
CountOfQuestion3 11
I need to be able to sort this based on the numbers, so I know which count was the highest. I hope to get:
CountOfQuestion1 34
CountOfQuestion3 11
CountOfQuestion2 7
I feel like I'm missing something obvious, but any help would be much appreciated.
Thanks!
It would seem you want the results in rows rather than in columns. One way to accomplish this is to use separate queries for each question count and then use the union operator to merge the results together like this:
SELECT
'Q1' AS Question, Count(IIf([Survey].[Question1]=True,1,Null)) AS QuestionCount
FROM Survey
UNION ALL
SELECT
'Q2' AS Question, Count(IIf([Survey].[Question2]=True,1,Null)) AS QuestionCount
FROM Survey
UNION ALL
SELECT
'Q3' AS Question, Count(IIf([Survey].[Question3]=True,1,Null)) AS QuestionCount
FROM Survey
ORDER BY QuestionCount DESC
This would give output looking like this:
Question QuestionCount
-------- -------------
Q2 4
Q1 3
Q3 2
In Access Yes/No fields can be summed, so the following should work.
Select ABS(Sum(Question1)) as CountOfQuestion1, ABS(Sum(Question2)) as CountOfQuestion2
FROM Survey

N or more continuous year range

I have to create a report using MySql DB where more than 4 tables are involved. I have one table (S1) with S1_ID and S1_Year_Range (strings like 2001-2002) and another table (S2) with S2_ID(PK), S2_Customer_ID, S1_ID (FK) and other fields for other conditions that can appear in Where clause of my query. There can be more than one row in S2 with the same S2_Customer_ID but different S1_ID. My query is to create a report using VB.net and ask users to enter two values; one number for how many continuous years or bigger (like >= 5 years), and a year range value (like 2011-2012) which is the highest value in the list for all customers.
My report lists customer names (by joining the above query with another table), customer rank and all year range values (highest at the bottom) for that customer in one column for each customer. Any help for this query would be appreciated.
Data and results could be like the following:
S1:
(S1_ID....S1_Year_Range)
(1......2000-2001)
(2......2001-2002)
(3......2002-2003)
(4......2003-2004)
(5......2004-2005)
etc
S2:
(S2_ID.....S2_Customer_ID.....S1_ID)
(1....1....1)
(2....1....2)
(3....1....3)
(4....2....2)
(5....2....3)
(6....2....5)
(7....3....2)
(8....3....3)
(9....3....4)
(10...3....5)
(11...4....3)
(12...4....4)
(13...4....5)
etc
when number 2 and year range (2003-2004) is entered by the user, the result should be the following:
customer 3 with 3 year range values (2003-2004, 2002-2003, and 2001-2002) and customer 4 with 2 year range values (2003-2004 and 2002-2003):
cname3
2001-2002
2002-2003
2003-2004
cname4
2002-2003
2003-2004
I hope you can see the columns of the report correctly.
I finally created a complex query to solve my problem. In the following query, I encoded the user year range value as '2010-2011' and number of continuous years as 14. Also a tiny difference with the question is the table names; table CSP here is the same as table S2 in my question but field names are the same as those in my question.
SELECT CSYWFY.S2_Customer_ID, COUNT(CSYWFY.S2_Customer_ID)
FROM (SELECT S1F.S1_Year_Range, S2.S2_Customer_ID , COUNT(S1F.S1_Year_Range) FROM CSP as S2 INNER JOIN S1 as S1F ON S2.S1_ID = S1F.S1_ID WHERE '2010-2011' IN (SELECT S1N.S1_Year_Range FROM CSP as S2N INNER JOIN S1 as S1N ON S2N.S1_ID = S1N.S1_ID WHERE S2N.S2_Customer_ID = S2.S2_Customer_ID ) GROUP BY S2.S2_Customer_ID ASC , S1F.S1_Year_Range DESC ) CSYWFY
GROUP BY CSYWFY.S2_Customer_ID
HAVING COUNT(CSYWFY.S2_Customer_ID) > 14
HTH