Exchanging rows and columns in - sql

I am looking for a way to somehow bring the information of different rows in to different/one column.
This is the problem:
Assume that I have 10 different sellers and 1000 buyers.
Currently this is how data structured (picture)
So for each sale, I have a row with the id of the seller and a buyer who bought something from him. What I want to have is to have 1 row for each seller and then in one/different columns I want to see the id of the buyer.
I am using snowflake and read about different ways but none of them really works.
I also have a timestamp column in this table and the only thing that I could think up until now is to
SELECT seller,
rank()over(partition by seller order by purchase_date desc)
and after that I can use aggregation functions - this is not really a wise solution and not really practical when I have 10 -20 or more buyers.
What is the best approach for solving these types of problems?

You should be able to do this using listagg function as per the snowflake documentation
https://docs.snowflake.com/en/sql-reference/functions/listagg.html
--This will create a concatenated list of buyers seperated by a comma
select seller
,listagg(buyer,',') within group(order by buyer)
from table
group by seller

Related

Oracle SQL: Show Individual Count Even if There are Duplicates

this is my first question on here, so please forgive me if I break any rules.
Here is what I need to know:
How do I create an Oracle SQL query that will display a unique count of something even if there are duplicates in the results?
Example: a customer table has a list of purchases made by various customers. The table lists the customer ID, name, category of purchase (ie Hardware, Tools, Seasonal) ect. The outcome of the query needs to show each customer id, customer name and the category of the purchase, and a count of the individual customer. SO customer ID 1 for John Smith has made a purchase in each department. If I do a count of the customer, he will appear three times as he has made three purchases, but I also need a column to count the customer only once. The count in the other rows returned for the other departments should show a 0 or Null.
I normally achieve this by pulling everything and exporting to excel. I add a column that uses an IF formula on the ID to only show a 1 on the first occurrence of the customer IE: IF(A3=A2,0,1) (if a3 is the same as A2, show a 0, if it's not the same as A2 then show a 1). This will give me a unique count of customers for one part of the report and will still show me how many purchase the customer made in another part of the report.
I want to do this directly in the SQL query as I have a large set of data this needs to be done on, and adding any formulas in excel will make the sheet huge. This will also make it easier to host the query results in ACCESS so excel can pull it from there.
I have tried to find a solution to this for a while, but any searching on Google will usually return results on how to remove duplicates form a table or how to count the duplicates in a table.
I am sorry if this is long question, but I wanted to be through so I do not waste anyone's time on back an fourth comments (I have seen this many times on here and else where when the OP asks a very cryptic question and expects everyone to understand them without further expiation).
Using distinct can be used in a count to only count the unique values of a field.
SELECT
cust.customer_id, cust.customer_name, p.category,
count(distinct p.department_id) as total_departments,
count(*) as total_purchases
FROM customers cust
LEFT JOIN purchase_table p on (cust.customer_id = p.customer_id)
GROUP BY cust.customer_id, cust.customer_name, p.category
ORDER BY cust.customer_id;
Such method is not limited to the Oracle RDBMS.

Access query/SQL - duplicates in one field with distinct multiple 2nd field

I am working on a database with products and lot numbers. Each entry in the Lots table has a Lot Number and a Product description.
Sometimes there are multiple records of the same lot number, for example when an item is repacked a new record is created, but with the same Lot Number and same product description - this is fine. But other times there are problem cases, namely when two different products share the same Lot Number. I am trying to find those.
In other words, there are 3 possibilities:
Lot numbers for which there is only one record in the table.
Lot numbers for which there are multiple records, but the Product description is the same for all of them
Lot numbers for which there are multiple records, and the product descriptions are not all the same.
I need to return only #3, with a separate record for each instance of that Lot Number and product description.
Any help would be greatly appreciated.
Thanks Juan for the sample data. Using this example, I want to return the data contained in Id 2-8, but not 1, 9, 10, 11.
This wasn't easy because lot of time don't use access.
First select unique values using distinct.
Then count how many diferent product appear on each lotnumber using group by
Last join both result and show only the lots with more than one description where total >1
.
SELECT id, Product.lotnumber, Product.Product, total
FROM
Product Inner join
(
SELECT lotnumber, count(*) as total
FROM
(SELECT distinct lotnumber, product
FROM Product)
GROUP BY lotnumber
) SubT On Product.lotnumber = SubT.lotnumber
WHERE total > 1
ORDER BY id
As you can see :
lot 2 have two products (yy and zz)
lot 3 have thre products (aa, bb, cc)
I include my product table:
Sorry for spanish. Field types are Autonumeric, Short Text, and Number

Using VBA to get the sum of values based on criteria from other tables?

I need to find the sum of the prices of a number of products, however the prices are stored in a different table to products that need pricing.
But, there is a catch, it needs to select these items based on criteria from a third table too.
So, I need the sum of the price of all products in Table 1 where CutID in Table 2 = 001.
Table 1 and Table 2 are linked on SCID, one to many respectively.
If this makes no sense tell me and I will try to clarify?
Thanks,
Bob P
Based on your question, I don't think there's a need for VBA. Excel formulas should be sufficient.
Add a few columns to your primary table. In these columns, use vlookup() to get all your information in one place, including the criteria.
If you only need to sum based on one criteria, use sumif(). If there's multiple criteria, use sumproduct().
Generally, with Access, I initially try to work with something as close a possible to a standard SQL query for ease of maintenance and portability. This ran for me in Access 2010:
SELECT Products.ProductID, Sum(Prices.Price) AS PriceSum
FROM Prices INNER JOIN (Critera INNER JOIN Products ON Critera.SCID = Products.SCID) ON Prices.ProductID = Products.ProductID
WHERE Critera.CutID="001"
GROUP BY Products.ProductID;
Please let us know if that works with your data (I'm not sure of your column names, either).

Select records for MySQL only once based on a column value

I have a table that stores transaction information. Each transaction is has a unique (auto incremented) id column, a column with the customer's id number, a column called bill_paid which indicates if the transaction has been paid for by the customer with a yes or no, and a few other columns which hold other information not relevant to my question.
I want to select all customer ids from the transaction table for which the bill has not been paid, but if the customer has had multiple transactions where the bill has not been paid I DO NOT want to select them more than once. This way I can generate that customer one bill with all the transactions they owe for instead of a separate bill for each transaction. How would I build a query that did that for me?
Returns exactly one customer_id for each customer with bill_paid equal to 'no':
SELECT
t.customer_id
FROM
transactions t
WHERE
t.bill_paid = 'no'
GROUP BY
t.customer_id
Edit:
GROUP BY summarises your resultset.
Caveat: Every column selected must be either 'grouped by' or aggregated in some fashion. As shown by nikic you could use SUM to get the total amount owed, e.g.:
SELECT
t.customer_id
, SUM(t.amount) AS TOTAL_OWED
FROM
transactions AS t
WHERE
t.bill_paid = 'no'
GROUP BY
t.customer_id
t is simply an alias.
So instead of typing transactions everywhere you can now simply type t. The alias is not necessary here since you query only one table, but I find them invaluable for larger queries. You can optionally type AS to make it more clear that you're using an alias.
You might try the Group By operator, eg group by the customer.
SELECT customer, SUM(toPay) FROM .. GROUP BY customer

How to count unique records and get number of these uniques in table using SQL?

Imagine I have table like this:
id:Product:shop_id
1:Basketball:41
2:Football:41
3:Rocket:45
4:Car:86
5:Plane:86
Now, this is an example of large internet mall, where there are shops which sell to one customer, so customer can choose more products from each shop and buy it in one basket.
However, I am not sure if there is any SQL syntax which allows me to simply get unique shop_ids and total number of those shops' products in customer basket. So I'd get something like:
Shop 41 has 2 products
Shop 45 one product
Shop 86 two product
I can make SQL queries to scoop through table to make some kind of ['shop_id']['number_of_products'] array variable that would store all products' shop_ids, then "unique them" - up and count how many times I had to cut one more shop_id out to have some remaining but that just seems as a lot of useless scripting.
If you got some nice and neat idea, please, let me know.
This is exactly the sort of thing that aggregate functions are for. You make one row of output for each group of rows in the table. Group them by shop_id and count how many rows are in each group.
select shop_id, count(1) from TABLE_NAME
group by shop_id