Matching Different Value within One Row II - mysql

this is a revised question from previous one. I decided to open a new question since the scope has changed.
This is what I want to achieve.
List the last name of the author(s) of the book in an "Author" column, the last name of the author to be listed first, followed (after a comma) by that of the author to be listed second if any; and if there is a third author, put it after the second author's name. The order of the author of a book is listed in the au_ord column (1=First Author, 2=Second Author, 3=Third Author).
Any idea how to achieve this in MYSQL output?
Those are the source table. The desired output is something like this:

This should give your first sample output:
SELECT title_id, au_ord, au_lname
FROM title_authors
LEFT JOIN authors
ON authors.au_id = title_authors.au_id
WHERE title_id = 'TC7777'
ORDER BY au_ord;
and this should give the second:
SELECT title_id, GROUP_CONCAT(au_lname ORDER BY au_ord SEPARATOR ', ')
FROM title_authors
LEFT JOIN authors
ON authors.au_id = title_authors.au_id
GROUP BY title_id
HAVING title_id = 'TC7777';

All you need is a GROUP_CONCAT function.
SELECT title_id, GROUP_CONCAT(au_lname ORDER BY au_ord)
FROM table
GROUP BY title_id
The GROUP BY clause groups all individual (distinct) titles, and the GROUP_CONCAT on it concatenates all the authors of it. This would list all the titles and their corresponding authors. If au_lname is from another table than from title_id table, then you will have to use appropriate joins. I am not sure what are the table names from your question.

Related

Why are Duplicates not being filtered out

I am working on some practice interview Questions and am struggling with this:
You are working with a company that sells goods to customers, and they'd like to keep track
of the unique items each customer has bought. The database is composed of two tables:
Customers and Orders. The two table schemas are given below. We want to know what
unique items were purchased by a specific customer, Wilbur, and when they were
purchased. What is the correct query that returns the customer first name, item
purchased, and purchase date with recent purchases first?
Tables: https://imgur.com/a/D47R1KU
My answer so far is
However I am getting an incorrect message as its Printing wilbur,oranges,2019-06-10
and wilbur,oranges,2018-06-10 instead of just the one with the more recent date. Please see the picture for the two tables referenced by the question. Thanks!
Between the where clause and ORDER BY, try:
GROUP BY FirstName, Item
And to get the most recent date, select MAX(PurchaseDate).
The query you are looking for is as follows.
This uses group by to indicate which columns should be grouped together, and for the column that's not grouped, how to choose which value of many to use, in this case the max value.
Note also the use of explicit, clear, SQL-92 modern join syntax and meaningful column aliases to show which table each column originates from. Distinct is not needed since each group is already unique.
Select c.FirstName, o.Item, Max(o.PurchaseDate) PurchaseDate
from Customers c
join Orders o on o.PersonId=p.PersonId
where c.FirstName = 'Wilbur'
group by c.firstName, o.Item
order by Max(o.PurchaseDate) desc;

Using COUNT(Distinct ) in SQL

Here is a database schema:
customers (custID, firstname, familyname, town, state)
orders (orderID, custlD, date)
lineitems (orderID, itemlD, quantity, despatched)
items (itemID, description, unitcost, stocklevel)
itemSupplier (supplierID, itemlD)
supplier (supplierID, sName, sAddress, telephoneNo, delivers)
Here is the question:
If we assume that the description field in the items table uses a set of pre-defined categories (e.g., tents, spades, etc), then we can answer questions like, 'how many different kinds of tent does the shop sell?' Write a SQL query to list all items for which more than one of the same kind of item is sold and to find how many different types of that item are sold (i.e., a list with colunm headings: description; 'how many types are sold').
I tried to use DISTINCT in COUNT() function like this:
SELECT description, count(DISTINCT itemID) AS how_many_types_are_sold
FROM items
GROUP BY description
I'm not sure whether it's a right use of the functions or not. Is there any advice to solve this question? Thanks in advance:D
This query:
SELECT description, count(DISTINCT itemID) AS how_many_types_are_sold
FROM items
GROUP BY description;
Based on your description, this does what you want to do. But . . . you should be using DISTINCT only when necessary.
There is a really good chance that a column called itemID in a table called items is actually the primary key for the table. If so, then each row has a distinct value, and the COUNT(DISTINCT) is redundant. Based on this assumption, you can just count the number of rows that match:
SELECT description, count(*) AS how_many_types_are_sold
FROM items
GROUP BY description;
This is much preferred (because count(*) performs better than count(distinct)), assuming that itemID is unique in the table.
From my understanding, you do not need distinct in your select statement, as the group by will group every item based description which means,
SELECT description, count(*) AS how_many_types_are_sold FROM items GROUP BY description
but you can use above statement if only and if all the categories are predefined as you mentioned in your question, otherwise some not defined descriptions will be expected, in this case you need some kind of mapping table to map all the descriptions with all categories you have.

mySQL - use an outer query value as a column name for a subquery

I have one table that holds exam questions; another table that holds exam answers.
I want to develop a query that will list the exam questions, and the most common answer for each one.
The relevant parts of the questions table is like this:
name question_text
ex1_qs1 1. What is furry and has four legs?
ex1_qs2 2. What is hairless and has two legs?
The relevant parts of the responses table is like this:
session_id ex1_qs1 ex1_qs2
123456789 cat man
112233445 dog woman
111222333 dog woman
I know I can get the list of questions like this:
Select name, question_text
From questions
Order By LENGTH(name), name
And the most common response for each question like this:
SELECT ex1_qs1
FROM responses
GROUP BY ex1_qs1
ORDER BY COUNT(*) DESC LIMIT 1
But I'm not seeing how to put it all together as a subquery, since the column name that I need for the subquery is a value from the main query. I can't hardcode this as a bunch of UNIONs either.
What do I use below instead of the hardcoded "ex1_qs1" (since I need to use the value of the "name" field in the outer query)? Or is there another approach needed?
Select name, question_text, (SELECT ex1_qs1 FROM responses GROUP BY ex1_qs1 ORDER BY COUNT(*) DESC LIMIT 1) as most_common_response
From questions
Order By LENGTH(name), name

Matching Different Value within One Row

I want to perform a query whereby I want to check whether on the columns A has either certain values. A could have only X , X and Y or a combination of X Y and Z.
To give a better understanding. I am checking a book's author within a table itself. The table has the BOOK_ID , BOOK_TITLE , AUTHOR_NAME, AUTHOR_ORDER.
So a book might have 1,2 or 3 authors, listed in order written inside the AUTHOR_ORDER row. I am trying very hard to reach an output where if a book has 3 authors, it will display accordingly from the first author to the third author. I am now stuck in the part where I need to compare the value and present it in the output.
Any idea how to achieve this in MYSQL output?
Sample :
The output result is more or less like this:
If the title has au_ord of 1,2 and 3, there shall be a new column with all the authors name listed in ascending.
So for example, for title BU1032, the Author row will be Bennet, Green
I think GROUP_CONCAT is what you are after:
SELECT Title_ID,
Title,
GROUP_CONCAT(au_LName ORDER BY au_Ord) AS Authors
FROM Books
GROUP BY Title_ID, Title;
SQL FIDDLE

MySQL: grab one row from each category, but remove duplicate rows posted in multiple categories

I have a database of articles, which are stored in categories. For my homepage, I want to grab an article from each category (I don't care which). However, some articles are crossposted to multiple categories, so they come up twice.
I have a table called tblReview with the article fields (reviewID, headline, reviewText) and a table called tblWebsiteContent that tells the site which categories the articles are in (id, reviewID, categoryID) and finally, a table called tblCategories (categoryID, categoryName) which stores the categories.
My query basically joins these tables and uses GROUP BY tblCategory.categoryID. If I try adding 'tblReview.reviewID' into the GROUP BY statement, I end up with hundreds of articles, rather than 22 (the number of categories I have).
I have a feeling this needs a subquery but my test efforts haven't worked (not sure which query needs to contain my joins / field list / where clause etc).
Thanks!
Matt
SELECT T.categoryName, tR.headline, tR.reviewText
FROM (
SELECT tC.categoryName, MAX(tR1.reviewID) reviewID
FROM tblReview tR1 join tblWebsiteContent tWC on tR1.reviewID = tWC.reviewID
join tblCategory tC on tC.categoryID = tWC.categoryID
GROUP BY tC.categoryName) T JOIN
tblReview.tR on tR.reviewID = T.reviewID
this query will select for each category an article headline corresponding to the Max reviewId for that category (you said 'I don't care which')
Try using SELECT DISTINCT. (This will only work if your SELECT is only pulling the article ID.)
select DISTINCT reviewID