Counting and presenting only duplicates - google-bigquery

So I have a table like this:
Name | Fruit | price
----------------------
Effy | Apple| 8
Effy | Banana | 9
Alam | Apple | 8
Alam | Banana | 10
Boji | Apple | 11
Suppose I want to get rid only from the Names that has one value (like Boji). How can I do it in big Query?
I thought to add HAVING clause and to add Having count(*) > 2, since this table is already grouped by,
but i's no working the way I want.
Select Distinct name, fruit, price from fruit_db
group by name, fruit
output:
Name | Fruit | price
----------------------
Effy | Apple| 8
Effy | Banana | 9
Alam | Apple | 8
Alam | Banana | 10

Try below
select * except(qualified) from (
select *,
count(1) over(partition by name) > 1 qualified
from `project.dataset.table`
)
where qualified
if applied to sample data in your question - output is

Related

How to select values, where each one depends on a previously aggregated state?

I have the following table:
|-----|-----|
| i d | val |
|-----|-----|
| 1 | 1 |
|-----|-----|
| 2 | 4 |
|-----|-----|
| 3 | 3 |
|-----|-----|
| 4 | 7 |
|-----|-----|
Can I get the following output:
|-----|
| sum |
|-----|
| 1 |
|-----|
| 5 |
|-----|
| 8 |
|-----|
| 1 5 |
|-----|
using a single SQLite3 SELECT-query? I know it could be easily achieved using variables, but SQLite3 lacks those. Maybe some recursive query? Thanks.
No.
In a relational database table rows do not have any order. If you specify an order for the rows, then it's possible to write a query.
Now, you could add an extra column to sort the rows. For example:
| val | sort
|-----|-----
| 1 | 10
| 4 | 20
| 3 | 30
| 7 | 40
The query could be:
select
sum(val) over(order by sort)
from my_table
For the updated question, you can write:
select
sum(val) over(order by id)
from my_table
By using the order of the id column and if you want only the sum column, you can do this:
select (select sum(val) from tablename where id <= t.id) sum
from tablename t

Summarise Data based on an Account within a Query using SQL

Come up against an issue where i want to summarize results in a query.
Example being as follows:
NAME | FRUIT | PRICE
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | APPLE | 2
DAVE | GRAPE | 3
DAVE | GRAPE | 3
DAVE | GRAPE | 3
This is my table at the moment, what i need though is to have a summary of Johns business, like below:
NAME | FRUIT | PRICE
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | APPLE | 2
JOHN | TOTAL | 8
DAVE | GRAPE | 3
DAVE | GRAPE | 3
DAVE | GRAPE | 3
I have tried to group the information but it does not reflect what i want, plus if John were to have different fruit it would need to sum that up before it sums up the next part.
Any advice would be great
Why do you want a summary only of John? You can use union all for this:
select name, fruit, price
from ((select name, fruit, price, 1 as ord, fruit as f
from t
) union all
(select name, 'Total', sum(price), 2 as ord, fruit as f
from t
where name = 'John'
group by name, fruit
)
) x
order by name, f, ord;

How to aggregate from result data Oracle SQL?

I have table :
+------+-------+-----------------+
| id | name | code | desc |
+------+-------+-----------------+
| 1 | aa | 032016 | grape |
| 1 | aa | 012016 | apple |
| 1 | aa | 032016 | grape |
| 1 | aa | 022016 | orange |
| 1 | aa | 012016 | apple |
| 1 | aa | 032016 | grape |
+------+-------+-----------------+
i tried with query:
SELECT id, name, code, desc, COUNT(code) as view
FROM mytable
GROUP BY id, name, code, desc
and the result is :
+------+-------+------------------------+
| id | name | code | desc | view |
+------+-------+------------------------+
| 1 | aa | 012016 | apple | 2 |
| 1 | aa | 022016 | orange | 1 |
| 1 | aa | 032016 | grape | 3 |
+------+-------+------------------------+
what i expected is like this :
+------+-------+----------------------------------------------------+
| id | name | code | desc | view |
+------+-------+----------------------------------------------------+
| 1 | aa | 012016,022016,032016 | apple,orange,grape | 2,1,3 |
+------+-------+----------------------------------------------------+
can anyone help me how to aggregate the result?
thanks in advance
Your table design has me a bit worried. Is it coincidence that one fruit always has the same code in the table? Then why store it redundantly? There should be a fruit table holding each fruit and its code only once. You know why this is called a relational database system, don't you?
However, with your query you are almost where you wanted to get. You have the counts per id, name, code, and desc. Now you want to aggregate even further. So in the next step group by id and name, because you want one result row per id and name it seems. Use LISTAGG to concatenate the strings in the group:
SELECT
id,
name,
listagg(code, ',') within group(order by code) as codes,
listagg(desc, ',') within group(order by code) as descs,
listagg(view, ',') within group(order by code) as views
FROM
(
SELECT id, name, code, desc, COUNT(*) as view
FROM mytable
GROUP BY id, name, code, desc
)
GROUP BY id, name
ORDER BY id, name;

Applying distinct in multiple columns in SQL server

I am trying to get distinct result by only one column( message). I tried
SELECT DISTINCT
[id], [message]
FROM Example table
GROUP BY [message]
But it doesn't show desired result.
Please let me know how can I do it?
Example table:
id | Message |
-- ------------
1 | mike |
2 | mike |
3 | star |
4 | star |
5 | star |
6 | sky |
7 | sky |
8 | sky |
Result table:
id | Message |
-- ------------
1 | mike |
3 | star |
6 | sky |
Group by the column you want to be unique and use an aggregate function on the other column. You want the lowest id for every message, so use MIN()
select min(id) as id,
message
from your_table
group by message

Mysql query: combine two queries

Below is an over-simplified version of table I'm using:
fruits
+-------+---------+
| id | type |
+-------+---------+
| 1 | apple |
| 2 | orange |
| 3 | banana |
| 4 | apple |
| 5 | apple |
| 6 | apple |
| 7 | orange |
| 8 | apple |
| 9 | apple |
| 10 | banana |
+-------+---------+
Following are the two queries of interest:
SELECT * FROM fruits WHERE type='apple' LIMIT 2;
SELECT COUNT(*) AS total FROM fruits WHERE type='apple'; // output 6
I want to combine these two queries so that the results looks like this:
+-------+---------+---------+
| id | type | total |
+-------+---------+---------+
| 1 | apple | 6 |
| 4 | apple | 6 |
+-------+---------+---------+
The output has to be limited to 2 records but it should also contain the total number of records of the type apple.
How can this be done with 1 query?
SELECT *, (SELECT COUNT(*) AS total FROM fruits WHERE type='apple') AS Total
FROM fruits WHERE type='apple' LIMIT 2;
Depending on how MySQL interprets it, it may cache the inner query so that it doesn't have to reevaluate it for every record.
Another way to do it is with a nested query and a join (this would be useful it you need more than one fruit type, for example):
SELECT fruits.*, counts.total
FROM fruits
INNER JOIN (SELECT type, COUNT(*) AS total FROM fruits GROUP BY type) counts ON (fruits.type = counts.type)
WHERE fruits.type='apple'
LIMIT 2;
You should use SQL_CALC_FOUND_ROWS for that.
SELECT SQL_CALC_FOUND_ROWS * FROM fruits WHERE type='apple' LIMIT 2;
will return the IDs of your apples, and remember how much it would have returned without the LIMIT clause
SELECT FOUND_ROWS();
will return how many apples would have been found, without the limit statement.