I'm facing problem when trying to extract row that based on condition from another row.
Sample table:
GroupID | Name | Salary | Car
--------------------------------------------------------------------------------
9009 | Isaac | 10,000 | Honda
9009 | Ricky | | Nissan
9080 | Patrick | 20,000 | Ferrari
9080 | Susan | 30,000 | Nissan
Questions:
How should I query if I want to extract data like this:
GroupID | Name | Salary | Car
--------------------------------------------------------------------------------
9009 | Isaac | 10,000 | Honda
9080 | Patrick | 20,000 | Ferrari
based on condition car = Nissan?
Try this:
SELECT GroupID, Name, Salary, Car
FROM tableName
WHERE GroupID IN (SELECT GroupID
FROM tableName
WHERE Car = 'Nissan') -- << Your input
AND car <> 'Nissan'
Read more about subqueries here.
SELECT * FROM yourTable where Car <> 'Nissan';
Would seem to do what you asked for.
You need to be more explicit about what you are trying to achieve here.
Related
I can't give the actual table, but my problem is something like this:
Assuming that there is a table called Names with entries like these:
+--------------+
| name | id |
+--------------+
| Jack | 1001 |
| Jack | 1022 |
| John | 1010 |
| Boris | 1092 |
+--------------+
I need to select all the unique names from that table, and display them(only names, not ids). But if I do:
SELECT DISTINCT name FROM Names;
Then it will return:
+-------+
| name |
+-------+
| Jack |
| John |
| Boris |
+-------+
But as you can see in the table, the 2 people named "Jack" are different, since they have different ids. How do I get an output like this one:
+-------+
| name |
+-------+
| Jack |
| Jack |
| John |
| Boris |
+-------+
?
Assuming that some ids can or will be repeated(not marked primary key in question)
Also, in the question, the result will have 1 column and some number of rows(exact number is given, its 18,013). Is there a way to check if I have the right number of rows? I know I can use COUNT(), but while selecting the unique values I used GROUP BY, so using COUNT() would return the counts for how many names have that unique id, as in:
SELECT name FROM Names GROUP BY id;
+------------------+
| COUNT(name) | id |
+------------------+
| 2 | 1001 |
| 1 | 1022 |
| 1 | 1092 |
| 3 | 1003 |
+------------------+
So, is there something to help me verify my output?
You can use group by:
select name
from names
group by name, id;
You can get all the distinct persons with:
SELECT DISTINCT name, id
FROM names
and you can select from the above query only the names:
SELECT name
FROM (
SELECT DISTINCT name, id
FROM names
)
I have a table (as table1)comes from HBase that has certain things that I would like to filter out. I have recreated the table, my SQL query, and the output I receive below. What happens is that when I try to filter out the string value it stays in the table, even if I want it out.
table1 ( some positions are fully capitalized some arent, want to make them all capitalized and filter out positions )
name | company | personal_id | position
Joe | Applebees| 32 | manager
Jack | Target | 12 | CLERK
Jim | Chipotle | 22 | COOK
Ron | Starbucks| 13 | barista
query
df = sqlContext.sql("select name, company, personal_id, UCASE(position) as position
from table1
where position != 'BARISTA'") #tried lower & upper case
Output Reieved
name | company | personal_id | position
Joe | Applebees| 32 | MANAGER
Jack | Target | 12 | CLERK
Jim | Chipotle | 22 | COOK
Ron | Starbucks| 13 | BARISTA /*dont want this output*/
Why did the row Ron | Startbucks| 13 | BARISTA not filter with my where clause?
try
where UCASE(position) != 'BARISTA'
Why are you grouping the result. there is no need to group the result until aggregate function is used. Try below query -
select name, company, personal_id, UCASE(position) as position
from table1
where upper(position) != 'BARISTA'
Here are the two tables i have: [all columns in both tables are of type "text"], Table name and the column names are in bold fonts.
Names
--------------------------------
Name | DoB | Team |
--------------------------------
Harry | 3/12/85 | England
Kevin | 8/07/86 | England
James | 5/05/89 | England
Scores
------------------------
ScoreName | Score
------------------------
James-1 | 120
Harry-1 | 30
Harry-2 | 40
James-2 | 56
End result i need is a table that has the following
NameScores
---------------------------------------------
Name | DoB | Team | ScoreData
---------------------------------------------
Harry | 3/12/85 | England | "{"ScoreName":"Harry-1", "Score":"30"}, {"ScoreName":"Harry-2", "Score":"40"}"
Kevin | 8/07/86 | England | null
James | 5/05/89 | England | "{"ScoreName":"James-1", "Score":"120"}, {"ScoreName":"James-2", "Score":"56"}"
I need to do this using a single SQL command which i will use to create a materialized view.
I have gotten as far as realising that it will involve a combination of string_agg, JOIN and JSON, but haven't been able to crack it fully. Please help :)
I don't think the join is tricky. The complication is building the JSON object:
select n.name, n.dob, n.team,
json_agg(json_build_object('ScoreName', s.name,
'Score', s.score)) as ScoreData
from names n left join
scores s
ons.name like concat(s.name, '-', '%')
group by n.name, n.dob, n.team;
Note: json_build_object() was introduced in Postgres 9.4.
EDIT:
I think you can add a case statement to get the simple NULL:
(case when s.name is null then NULL
else json_agg(json_build_object('ScoreName', s.name,
'Score', s.score))
end) as ScoreData
Use json_agg() with row_to_json() to aggregate scores data into a json value:
select n.*, json_agg(row_to_json(s)) "ScoreData"
from "Names" n
left join "Scores" s
on n."Name" = regexp_replace(s."ScoreName", '(.*)-.*', '\1')
group by 1, 2, 3;
Name | DoB | Team | ScoreData
-------+---------+---------+---------------------------------------------------------------------------
Harry | 3/12/85 | England | [{"ScoreName":"Harry-1","Score":30}, {"ScoreName":"Harry-2","Score":40}]
James | 5/05/89 | England | [{"ScoreName":"James-1","Score":120}, {"ScoreName":"James-2","Score":56}]
Kevin | 8/07/86 | England | [null]
(3 rows)
I have two tables, source and target.
source:
+--------+------+-------------+
| Name | Year | City |
+--------+------+-------------+
| Toyota | 2002 | Los Angeles |
| Seat | 2012 | Madrid |
+--------+------+-------------+
target:
+----+---------+------+----------+
| ID | Name | Year | City |
+----+---------+------+----------+
| 1 | Bentley | 1969 | Budapest |
| 2 | Toyota | 1988 | New York |
| 3 | Ford | 2001 | Tokyo |
| 4 | Seat | 1995 | Madrid |
| 5 | Bugatti | 1995 | London |
+----+---------+------+----------+
I want to merge source into target. I know the MERGE command, it's fine. The issue is that the source has no column ID so that it won't match.
Since Name column in both are unique I only need to match if they are equal, then if not exists insert into target, if exists update target.
I could do it using NOT EXIST statement, but we are talking about billions of rows so MERGE would be a much quicker solution.
So can I somehow set the MERGE command to take only that column into account when matching?
Yes, you can:
MERGE target t
USING source s
ON t.name = s.name
WHEN NOT MATCHED
INSERT (Name, Year, City)
VALUES (s.Name, s.Year, s.City)
WHEN MATCHED THEN
UPDATE SET Year = s.Year,
City = s.City;
If your ID column in target is not IDENTITY column you can create sequence to populate it.
Consider the following table structure with data -
AdjusterID | CompanyID | FirstName | LastName | EmailID
============================================================
1001 | Sterling | Jane | Stewart | janexxx#sterlin.com
1002 | Sterling | David | Boon | dav#sterlin.com
1003 | PHH | Irfan | Ahmed | irfan#phh.com
1004 | PHH | Rahul | Khanna | rahul#phh.com
============================================================
Where AdjusterID is the primary key. There are no. of adjusters for a company.
I need to have a query that will list single adjuster per company. i.e. I need to get the result as -
========================================================
1001 | Sterling | Jane | Stewart | janexxx#sterlin.com
1003 | PHH | Irfan | Ahmed | irfan#phh.com
========================================================
If any one could help me that will be great.
One way:
SELECT * FROM Adjusters
WHERE AdjusterID IN(SELECT min(AdjusterID)
FROM Adjusters GROUP BY CompanyID)
There are a handful of other ways involving unions and iteration, but this one is simple enough to get you started.
Edit: this assumes you want the adjuster with the lowest ID, as per your example
I know the answer from Jeremy is a valid one, so I will not repeat it. But you may try another one using a so called tie-breaker:
--//using a tie-breaker. Should be very fast on the PK field
--// but it would be good to have an index on CompanyID
SELECT t.*
FROM MyTable t
WHERE t.AdjusterID = (SELECT TOP 1 x.AdjusterID FROM MyTable x WHERE x.CompanyID = t.CompanyID ORDER BY AdjusterID)
It could be better performance-wise. But even more useful it is if you had another column in the table and you wanted to select not just one for each company but the best for each company using some other column ranking as a criteria. So instead of ORDER BY AdjusterID, you would order by that other column(s).