To Merge two rows using SQL - sql

I am stuck in a situation where with my SQL query I am getting an output as below.
I want my output to be of single row so that the end user have a glance at the report and can easily guess which are the event that guy has attended as below.

If you want a single row, use GROUP BY:
select fname, lname, max(event1) as Event1, max(event2) as event2
from t
group by fname, lname;

Assuming that every person has events including both yes and no, you can use below query to generate your desired result. If both values are no, you will get no in result then.
SELECT fname,
lname,
max(event1) as event1,
max(event2) as event2
FROM t1
GROUP BY fname,
lname;
Result:
fname lname event1 event2
------------------------------
abc xyz yes yes
you can check the demo here

Related

finding duplicate rows with different IDs based on multiple columns

please forgive me if my jargon is off. I'm still learning!
I just started using Teradata, and to be honest has been a lot of fun. however, I have hit a road block that has stumped me for a while.
I successfully selected a table from a database that looks like:
ID service date name
1 service1 1/5/15 john
2 service2 1/7/15 steve
3 service3 1/8/15 lola
4 service4 1/3/15 joan
5 service5 1/5/15 fred
6 service3 1/3/15 joan
7 service5 1/8/15 oscar
Now I want to search the data base again to find any duplicate IDs (example: to see if service service1 with date 1/5/15 with name john exists on another row with a different ID.)
At first, I did something like this:
SELECT ID, service, date, name
FROM table
WHERE table.service = ANY(service1, service2, service3, service4, service5, service3, service5)
AND table.date = ANY('1/5/15', '1/7/15, '1/8/15', '1/3/15', '1/5/15', '1/3/15', '1/8/15')
AND table.name = ANY('john', 'steve', 'lola', 'joan', 'fred', 'joan', 'oscar');
But this is giving me more rows than I wanted.
example:
ID service date name
92 service3 1/8/15 steve
is of no use to me since I am looking for IDs that have the same combination of service, date, and name as of any of the other IDs in the above table.
something like this would be favorable:
ID service date name
609 service3 1/8/15 lola
since it matches than of ID 3.
I was curious to see if it were possible to treat the three columns (service, date, name) as a vector and maybe select the rows that match it that way?
ex
......
WHERE (table.service, table.date, table.name) = ANY((service3,1/8/15,lola), (service1, 1/5/15, john), ...etc)
My Teradata is down right now, So I have yet to try the above example. Nevertheless, any thoughts/feedback is greatly appreciated!
The following query may be what you are trying to achieve. This selects IDs for which the combination of service, date, and name appears more than once.
SELECT t1.ID
FROM yourTable t1
INNER JOIN
(
SELECT service, date, name
FROM yourTable
GROUP BY service, date, name
HAVING COUNT(*) > 1
) t2
ON t1.service = t2.service AND
t1.date = t2.date AND
t1.name = t2.name
This is a simple task for a Windowed Aggregate:
SELECT *
FROM tab
QUALIFY
COUNT(*) OVER (PARTITION BY service, date, name) > 1
This counts the number of rows with the same combination of values (like Tim Biegeleisen's Derived Table) but unlike a Standard Aggregate it keeps all rows. The QUALIFY is a nice Teradata syntax extension to avoid a Derived Table.
Don't hardcode values in your query unless you absolutely have to. Instead, take the query you already wrote and join to that.
SELECT dupes.*
FROM (your query) yourquery
JOIN table dupes
ON yourquery.service = dupes.service
AND yourquery.date = dupes.date
AND yourquery.name = dupes.name

SQL Statement with 3 conditions

I have two tables:
Name Forename CostCentre
Max Meier 11111
Paul Peters 22222
Kai Green 11111
CostCentre departmentCostCentre
11111 HR
22222 IT
Besides this I have a Searchfield and a combobox for the cost centre.
If I enter "a" in the searchfield and "11111" in cost centre, I'll get all records...
But I just want to get Max and Kai. Here's my SQL statement:
SELECT tbl_Employee.Name, tbl_Employee.Forename, tbl_Employee.CostCentre, tbl_Department.Department
FROM tbl_DepartmentINNER JOIN tbl_EmployeeON tbl_Department.CostCentre= tbl_Employee.CostCentre
WHERE tbl_Employee.Name Like "*a*" OR tbl_Employee.Forename Like "*a*"AND tbl_Mitarbeiter.CostCentre=44444;
I really don't know where's the error.... If I delete the name or forename condition it works fine, but with both I get weird results...
If you want the cost centre condition to always apply and for the name conditions to apply to either name, then you need to use parenthesis:
SELECT * FROM tbl_Employee
WHERE (tbl_Employee.Name Like 'a' Or
tbl_Employee.Forename Like 'a') And
tbl_Employee.CostCentre=22222;
Otherwise, And binds more closely than Or and you're instead saying that either the Name condition must match or that both the Forename and CostCentre conditions must match.
Your question did already include some parentheses in your code which I've removed. I'm not sure what they related to.
Based on updated query:
SELECT tbl_Employee.Name, tbl_Employee.Forename, tbl_Employee.CostCentre, tbl_Department.Department
FROM tbl_DepartmentINNER JOIN tbl_EmployeeON tbl_Department.CostCentre= tbl_Employee.CostCentre
WHERE
(
tbl_Employee.Name Like "*a*"
OR
tbl_Employee.Forename Like "*a*"
)
AND
tbl_Mitarbeiter.CostCentre=44444;
SELECT
*
FROM
tbl_Employee
WHERE
tbl_Employee.Name LIKE '%a%'
AND tbl_Employee.CostCentre = 11111;

GROUP BY and aggregate function query

I am looking at making a simple leader board for a time trial. A member may perform many time trials, but I only want for their fastest result to be displayed. My table columns are as follows:
Members { ID (PK), Forename, Surname }
TimeTrials { ID (PK), MemberID, Date, Time, Distance }
An example dataset would be:
Forename | Surname | Date | Time | Distance
Bill Smith 01-01-11 1.14 100
Dave Jones 04-09-11 2.33 100
Bill Smith 02-03-11 1.1 100
My resulting answer from the example above would be:
Forename | Surname | Date | Time | Distance
Bill Smith 02-03-11 1.1 100
Dave Jones 04-09-11 2.33 100
I have this so far, but access complains that I am not using Date as part of an aggregate function:
SELECT Members.Forename, Members.Surname, Min(TimeTrials.Time) AS MinOfTime, TimeTrials.Date
FROM Members
INNER JOIN TimeTrials ON Members.ID = TimeTrials.Member
GROUP BY Members.Forename, Members.Surname, TimeTrials.Distance
HAVING TimeTrials.Distance = 100
ORDER BY MIN(TimeTrials.Time);
IF I remove the Date from the SELECT the query works (without the date). I have tried using FIRST upon the TimeTrials.Date, but that will return the first date which is normally incorrect.
Obviously putting the Date as part of the GROUP BY would not return the result set that I am after.
Make this task easier on yourself by starting with a smaller piece of the problem. First get the minimum Time from TimeTrials for each combination of MemberID and Distance.
SELECT
tt.MemberID,
tt.Distance,
Min(tt.Time) AS MinOfTime
FROM TimeTrials AS tt
GROUP BY
tt.MemberID,
tt.Distance;
Assuming that SQL is correct, use it in a subquery which you join back to TimeTrials again.
SELECT tt2.*
FROM
TimeTrials AS tt2
INNER JOIN
(
SELECT
tt.MemberID,
tt.Distance,
Min(tt.Time) AS MinOfTime
FROM TimeTrials AS tt
GROUP BY
tt.MemberID,
tt.Distance
) AS sub
ON
tt2.MemberID = sub.MemberID
AND tt2.Distance = sub.Distance
AND tt2.Time = sub.MinOfTime
WHERE tt2.Distance = 100
ORDER BY tt2.Time;
Finally, you can join that query to Members to get Forename and Surname. Your question shows you already know how to do that, so I'll leave it for you. :-)

Ordering 2 columns on the same order

I have the table:
Example:
Name | Last Name
Albert Rigs
Carl Dimonds
Robert Big
Julian Berg
I need to order like this:
Name | Last Name
Albert Rigs (name)
Julian Berg (last name)
Robert Big (last name)
Carl Dimonds
I need something like, order by name and last name on the same ordering.
See on example, i have Name Albert, the next ordered name row its the Carl, but i have Big and Berg on last name, B > C so i get the last name order on second row.
It's like the two columns are the same but isn't.
It's hard to explaim, i'm sorry.
Its possible?
Thaks in advance.
To order by the minimum of (Name, Lastname), you could:
select *
from YourTable
order by
case
when Name > LastName then LastName
else name
end
A syntactic improvement on the Case, and allowing a ti-break on the other column.
select *
from my_table
order by least(name,last_name),
greatest(name,last_name)

SQL: How to select rows from a table while ignoring the duplicate field values?

How to select rows from a table while ignoring the duplicate field values?
Here is an example:
id user_id message
1 Adam "Adam is here."
2 Peter "Hi there this is Peter."
3 Peter "I am getting sick."
4 Josh "Oh, snap. I'm on a boat!"
5 Tom "This show is great."
6 Laura "Textmate rocks."
What i want to achive is to select the recently active users from my db. Let's say i want to select the 5 recently active users. The problem is, that the following script selects Peter twice.
mysql_query("SELECT * FROM messages ORDER BY id DESC LIMIT 5 ");
What i want is to skip the row when it gets again to Peter, and select the next result, in our case Adam. So i don't want to show my visitors that the recently active users were Laura, Tom, Josh, Peter, and Peter again. That does not make any sense, instead i want to show them this way: Laura, Tom, Josh, Peter, (skipping Peter) and Adam.
Is there an SQL command i can use for this problem?
Yes. "DISTINCT".
SELECT DISTINCT(user_id) FROM messages ORDER BY id DESC LIMIT 5
Maybe you could exclude duplicate user using GROUP BY.
SELECT * FROM messages GROUP BY user_id ORDER BY id DESC LIMIT 5;