Need to list the rows contained in a count(*) Access - sql

Hello everyone and thank you in advance for your help.
I'm having troubles with an SQL query in access.
I have
Database
I need the following output ( show and list the Store Number and PaidMoney ONLY where Paid money is the same amount 2 or more times only)
desired output
I already have 2 queries which kind of solve the problem, but each of the queries I have only solve 50% of the answer I need, the first lists all the results not only the duplicates , and the second query tells me how many duplicates there are but doesnt list and show the duplicates to me.
First Query
SELECT StoreNumber, PaidMoney
FROM Stores
Second query
SELECT StoreNumber, PaidMoney, COUNT(*)
FROM Stores
GROUP BY StoreNumber, PaidMoney
HAVING COUNT(*) > 1
Thank you all for your time and help!

You can join the 2 queries together and only "select" the columns from the first query. The second query will just filter out the rows from the first query that only appear once. Rows from the first query that appear more than once should appear as many times as they appear in the first query.
SELECT q1.StoreNumber, q1.PaidMoney
FROM (SELECT StoreNumber, PaidMoney
FROM Stores) q1
INNER JOIN (SELECT StoreNumber, PaidMoney, COUNT(*) ct2
FROM Stores
GROUP BY StoreNumber, PaidMoney
HAVING COUNT(*) > 1) q2
ON q1.StoreNumber = q2.StoreNumber
AND q1.PaidMoney = q2.PaidMoney

Related

How do I used distinct to remove duplicates in this query?

I have the following table: Table
I am trying to write a query (that I will include in another query) to display how many account numbers there are per symbol.
I wrote the following query:
SELECT Symbol,
(SELECT DISTINCT COUNT([Account Number]) FROM [Open] T2 WHERE T2.Symbol = T1.Symbol) AS Accounts
FROM Open T1
GROUP BY [Symbol];
The query displays like this but it counts the same account number multiple times per symbol. EURUSD should have 3 and USDJPY should only have 1 next to it.
It should display like this.
I am trying to include this as part of another big table that has other information next to each symbol too.
I will appreciate any assistance.
Access doesn't support count(DISTINCT ...). You can try
SELECT Symbol, count(*) AS Accounts
FROM (SELECT DISTINCT Symbol, Account FROM Open)
GROUP BY Symbol;

Select first three rows for each ID

I have executed the following query:
SELECT ProductID, Quantity, Location
FROM DBLocations
ORDER BY ProductID, LocationDistanceIndex DESC;
Afterwards, I've been trying to select up to 3 closest warehouses which have each of the products - LocationDistanceIndex column (Also there could be none, 1 or 2).
How would I write the query to remain with up to 3 records for each ProductID - the 3 records with the highest LocationDistanceIndex hence the descending order by.
Also if there is a way to perform such filtering without manually written queries in MS Access, it would be great if somebody points that out.
Note: I tried using Row_Number() Over Partition but MS Access does not seem to support that.
Here is one method for MS Access:
SELECT l.*
FROM DBLocations l
WHERE l.LocationDistanceIndex IN (SELECT TOP 3 l2.LocationDistanceIndex
FROM DBLocations l2
WHERE l.ProductID = l2.ProductID
ORDER BY l2.LocationDistanceIndex DESC
);

How to modify query to walk entire table rather than a single

I wrote several SQL queries and executed them against my table. Each individual query worked. I kept adding functionality until I got a really ugly working query. The problem is that I have to manually change a value every time I want to use it. Can you assist in making this query automatic rather than “manual”?
I am working with DB2.
Table below shows customers (cid) from 1 to 3. 'club' is a book seller, and 'qnty' is the number of books the customer bought from each 'club'. The full table has 45 customers.
Image below shows all the table elements for the first 3 users (cid=1 OR cid=2 OR cid=3). The final purpose of all my queries (once combined) is it to find the single 'club' with the largest 'qnty' for each 'cid'. So for 'cid =1' the 'club' is Readers Digest with 'qnty' of 3. For 'cid=2' the 'club' is YRB Gold with 'qnty' of 5. On and on until cid 45 is reached.
To give you a background on what I did here are my queries:
(Query 1-starting point for cid=1)
SELECT * FROM yrb_purchase WHERE cid=1
(Query 2 - find the 'club' with the highest 'qnty' for cid=1)
SELECT *
FROM
(SELECT club,
sum(qnty) AS t_qnty
FROM yrb_purchase
WHERE cid=1
GROUP BY club)results
ORDER BY t_qnty DESC
(Query 3 – combine the record from the above query with it’s cid)
SELECT cid,
temp.club,
temp.t_qnty
FROM yrb_purchase AS p,
(SELECT *
FROM
(SELECT club,
sum(qnty) AS t_qnty
FROM yrb_purchase
WHERE cid=1
GROUP BY club)results
ORDER BY t_qnty DESC FETCH FIRST 1 ROWS ONLY) AS TEMP
WHERE p.cid=1
AND p.club=temp.club
(Query 4) make sure there is only one record for cid=1
SELECT cid,
temp.club,
temp.t_qnty
FROM yrb_purchase AS p,
(SELECT *
FROM
(SELECT club,
sum(qnty) AS t_qnty
FROM yrb_purchase
WHERE cid=1
GROUP BY club)results
ORDER BY t_qnty DESC FETCH FIRST 1 ROWS ONLY) AS TEMP
WHERE p.cid=1
AND p.club=temp.club FETCH FIRST ROWS ONLY
To get the 'club' with the highest 'qnty' for customer 2, I would simply change the text cid=1 to cid=2 in the last query above. My query seems to always produce the correct results. My question is, how do I modify my query to get the results for all 'cid's from 1 to 45 in a single table? How do I get a table with all the cid values along with the club which sold that cid the most books, and how many books were sold within one tablei? Please keep in mind I am hoping you can modify my query as opposed to you providing a better query.
If you decide that my query is way too ugly (I agree with you) and choose to provide another query, please be aware that I just started learning SQL and may not be able to understand your query. You should be aware that I already asked this question: For common elements, how to find the value based on two columns? SQL but I was not able to make the answer work (due to my SQL limitations - not because the answer wasn't good); and in the absence of a working answer I could not reverse engineer it to understand how it works.
Thanks in advance
****************************EDIT #1*******************************************
The results of the answer is:
You could use OLAP/Window Functions to achieve this:
SELECT
cid,
club,
qnty
FROM
(
SELECT
cid,
club,
qnty,
ROW_NUMBER() OVER (PARTITION BY cid order by qnty desc) as cid_club_rank
FROM
(
SELECT
cid,
club,
sum(qnty) as qnty
FROM yrb_purchase
GROUP BY cid, club
) as sub1
) as sub2
WHERE cid_club_rank = 1
The inner most statement (sub1) just grabs a total quantity for each cid/club combination. The second inner most statement (sub2) creates a row_number for each cid/club combination ordering by the quantity (top down). Then the outer most query chooses only records where that row_number() is 1.

MS Access Query to retrieve records with lasted date in orderdate column

I have table in Access Database with the following columns
ProductID|ProductName|StoreID|StoreName|AuditRating|AuditVisit|NextAuditDue
100100 |Calculator |SC12345|CrawlyRoad| B |11/12/2013|21/02/2014
100100 |Calculator |SC12345|CrawlyRoad| A |11/12/2014|30/04/2015
100100 |Calculator |SC12345|CrawlyRoad| C |16/12/2015|24/01/2017
I need to make a query which will only give me the distinct record where the AuditVisit date is maximum like in this case I only want the third row
100100 |Calculator |SC12345|CrawlyRoad| C |16/12/2015|24/01/2017
I have used group by but as I need to bring all the columns I am getting all the records as the AuditRating column is different in all three rows.
You can use TOP 1:
Select Top 1 * From YourTable Order By AuditVisit Desc
You don't want to have groups, so why use group by?
SELECT
*
FROM your_table
WHERE AuditVisit = (SELECT MAX(AuditVisit) FROM your_table)
Pretty self-explaining, I think.
If you want one record in MS Access, then you need to be very careful with SELECT TOP. It is really SELECT TOP WITH TIES.
Hence, the obvious answer of:
Select Top 1 *
From t
Order By AuditVisit Desc;
would return multiple rows if multiple rows have the same date. If you really want one, then you want to add a unique column as the last key in the order by:
Select Top 1 *
From t
Order By AuditVisit Desc, id;
I don't see such a key in your data, although you might have a combination of columns that are unique in each row (multiple columns can be added to the ORDER BY).
In MS Access -- even more so than in other databases -- primary keys are important on tables for this reason.

Join query in Access 2013

Currently have a single table with large amount of data in access, due to the size I couldn't easily work with it in Excel any more.
I'm partially there on a query to pull data from this table.
7 Column table
One column GL_GL_NUM contains a transaction number. ~ 75% of these numbers are pairs. I'm trying to pull the records (all columns information) for each unique transaction number in this column.
I have put together some code from googling that hypothetically should work but I think I'm missing something on the syntax or simply asking access to do what it cannot.
See below:
SELECT SOURCE_FUND, GLType, Contract, Status, Debit, Credit, GL_GL_NUM
FROM Suspense
JOIN (
SELECT TC_TXN_NUM TXN_NUM, COUNT(GL_GL_NUM) GL_NUM
FROM Suspense
GROUP BY TC_TXN_NUM HAVING COUNT(GL_GL_NUM) > 1 ) SUB ON GL_GL_NUM = GL_NUM
Hey Beth is this the suggested code? It says there is a syntax error in the FROM clause. Thanks.
SELECT * from SuspenseGL
JOIN (
SELECT TC_TXN_NUM, COUNT(GL_GL_NUM) GL_NUM
FROM Suspense
GROUP BY TC_TXN_NUM
HAVING COUNT(GL_GL_NUM) > 1
Do you want detailed results (all rows and columns) or aggregate results, with one row per tx number?
If you want an aggregate result, like the count of distinct transaction numbers, then you need to apply one or more aggregate functions to any other columns you include.
If you run
SELECT TC_TXN_NUM, COUNT(GL_GL_NUM) GL_NUM
FROM Suspense
GROUP BY TC_TXN_NUM
HAVING COUNT(GL_GL_NUM) > 1
you'll get one row for each distinct txn, but if you then join those results back with your original table, you'll have the same number of rows as if you didn't join them with distinct txns at all.
Is there a column you don't want included in your results? If not, then the only query you need to work with is
select * from suspense
Considering your column names, what you may want is:
SELECT SOURCE_FUND, GLType, Contract, Status, sum(Debit) as sum_debit,
sum(Credit) as sum_credit, count(*) as txCount
FROM Suspense
group by
SOURCE_FUND, GLType, Contract, Status
based on your comments, if you can't work with aggregate results, you need to work with them all:
Select * from suspense
What's not working? It doesn't matter if 75% of the txns are duplicates, you need to send out every column in every row.
OK, let's say
Select * from suspense
returns 8 rows, and
select GL_GL_NUM from suspense group by GL_GL_NUM
returns 5 rows, because 3 of them have duplicate GL_GL_NUMs and 2 of them don't.
How many rows do you want in your result set? if you want less than 8 rows back, you need to perform some sort of aggregate function on each column you want returned.
You could do something like the following:
SELECT S.* FROM
SUSPENSE AS S
INNER JOIN (SELECT DISTINCT GL_GL_NUM, MIN(ID) AS ID FROM SUSPENSE
GROUP BY GL_GL_NUM) AS S2
ON S.ID = S2.ID
AND S.GL_GL_NUM = S2.GL_GL_NUM
Which would return a single row for a unique gl_gl_num. However if the other rows have different data it will not be shown. You would have to either aggregate that data up using SUM(Credit), SUM(Debit) and then GROUP BY the gl_gl_num.
I have attached a SQL Fiddle to demonstrate my results and make this clearer.
http://sqlfiddle.com/#!3/8284f/2