I have a select query with a subquery in it on table a:
select UserName, Name, anniversaryDate, RegionCode
from a where UserName in
(
select Username from
(
select Username, max(timeUsed)
from log_table where role='Cou'
group by Username order by max(timeUsed) desc limit 10
) a
)
which works fine, now I have another table called b,
on that table I only have 3 columns:
UserName, PName and feedback
which have each UserName multiple times and I want to join to my first query the count of each UserName I got from the first query.
for eaxmple:
SELECT COUNT(UserName) FROM b where UserName='Admin' group by UserName
How do I join the results from the second query to the first one?
Tables:
log_table :
id - Int, AI, PK
Username - varchar
Action - Int
timeUsed - Datetime
role - varchat
a:
UserName - varchar, PK
Name - varchar
anniversaryDate - Datetime
RegionCode - Int
b:
UserName - varchar
PName - varchar
feedback - varchar
Based on your table structure the query below might add the necessary column you are looking for:
select users.UserName, Name, anniversaryDate, RegionCode,
Coalesce(count(b.UserName),0) as cnt
from users
left outer join (select Username, max(timeUsed)
from log_table where role='Cou'
group by Username order by max(timeUsed) desc limit 10
) a using (UserName)
left outer join fedbacks b on (a.UserName = b.userName)
group by users.UserName;
Related
I have 2 Tables.
CustomerDetails table has columns ID, UUID, Name, Age.
FavoriteCustomers table has columns ID, UUID
CustomerDetails Table will have a lot of entries say 10000 rows. while FavoriteCustomers Table has very few entries. In CustomerDetails Table, ID and UUID form the combined unique ID.
Now I want the result to be combined row columns like below with a where clause.
ID, UUID, Name, Age, isFavorite WHERE Age is > 30
You could use either a sub-query or, as in the example below, a LEFT JOIN and check for a NULL value from the join.
select cd.ID, cd. UUID, cd.Name, cd.Age,
case when fc.ID is null then 'N' else 'Y' end as isFavorite
from CustomerDetails cd
left join FavoriteCustomers fc
on fc.ID = cd.ID
where cd.Age > 30;
In DBMS that support some kind of a boolean type you can use an EXISTS clause or an IN clause.
select
id, uuid, name, age,
(id, uuid) in (select id, uuid from favoritecustomers) as is_favorite
from customerdetails
where age > 30;
I have the following data:
I want to retrieve the ids that match the highest date (represented by max(folga)), grouping by funcionario_id.
Here's the output table I want, but it's missing the id:
How can I achieve this?
Thanks for the attention.
One way to do it is with NOT EXISTS:
select
t.funcionario_id, t.folga, t.id
from tablename t
where not exists (
select 1 from tablename
where funcionario_id = t.funcionario_id and folga > t.folga
)
or you can group by funcionario_id first to get the max date (I guess this is the query that returned the result you posted) and then join to the table:
select t.*
from tablename t inner join (
select funcionario_id, max(folga) folga
from tablename
group by funcionario_id
) g on g.funcionario_id = t.funcionario_id and g.folga = t.folga
I have 2 tables in MySQL t1 and t2. Both have same column names. Table t1 has huge data and t2 is not so huge as compared to t1 but in mean time t2 would also be of the same size as t1. The only difference is that the id column do not match in both the tables. I want to create a view out of these column.
What I have created is
CREATE VIEW vw_t1t2 AS SELECT id , name , lastname, depid FROM t1
Union
SELECT id , name , lastname, depid FROM t2;
If I do a query "Select * from vw_t1t2 where depid='100287'".
The view does not fetch the correct data, the data is mixture on all the records when I search for particular department id, some records are of different department id. Also it took 200 sec to execute the query.
you may consider to wrap the result of the union
SELECT * FROM
(
SELECT id , name , lastname, depid FROM t1
Union
SELECT id , name , lastname, depid FROM t2
) as sel1
WHERE depid = 2
but let us see the EXPLAIN output to optimize the query
I have a table with three fields user_name, page and n_loads. I would like to group the table by user_name, for each user name I would like to show maximal number of loads and the page that corresponds to this (maximal) number of loads. Can I do it in one MySQL clause?
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT username, MAX(n_loads) n_loads
FROM tableName
GROUP BY username
) b ON a.username = b.username AND
a.n_loads = b.n_loads
or
SELECT a.*
FROM tableName a
WHERE n_loads =
(SELECT MAX(b.n_loads)
FROM tableName b
WHERE a.username = b.username);
SQLFiddle Demo (both query)
I have a table defined like this:
CREATE TABLE mytable (id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id),
user_id INT REFERENCES user(id) ON UPDATE CASCASE ON DELETE RESTRICT,
amount REAL NOT NULL CHECK (amount > 0),
record_date DATE NOT NULL
);
CREATE UNIQUE INDEX idxu_mybl_key ON mytable (user_id, amount, record_date);
I want to write a query that will have two columns:
user_id
amount
There should be only ONE entry in the returned result set for a given user. Furthermore, the amount figure returned should be the last recoreded amount for the user (i.e. MAX(record_date).
The complication arises because weights are recorded on different dates for different users, so there is no single LAST record_date for all users.
How may I write (preferably an ANSI SQL) query to return the columns mentioned previously, but ensuring that its only the amount for the last recorded amount for the user that is returned?
As an aside, it is probably a good idea to return the 'record_date' column as well in the query, so that it is eas(ier) to verify that the query is working as required.
I am using MySQL as my backend db, but ideally the query should be db agnostic (i.e. ANSI SQL) if possible.
First you need the last record_date for each user:
select user_id, max(record_date) as last_record_date
from mytable
group by user_id
Now, you can join previous query with mytable itself to get amount for this record_date:
select
t1.user_id, last_record_date, amount
from
mytable t1
inner join
( select user_id, max(record_date) as last_record_date
from mytable
group by user_id
) t2
on t1.user_id = t2.user_id
and t1.record_date = t2.last_record_date
A problem appears becuase a user can have several rows for same last_record_date (with different amounts). Then you should get one of them, sample (getting the max of the different amounts):
select
t1.user_id, t1.record_date as last_record_date, max(t1.amount)
from
mytable t1
inner join
( select user_id, max(record_date) as last_record_date
from mytable
group by user_id
) t2
on t1.user_id = t2.user_id
and t1.record_date = t2.last_record_date
group by t1.user_id, t1.record_date
I do not now about MySQL but in general SQL you need a sub-query for that. You must join the query that calculates the greatest record_date with the original one that calculates the corresponding amount. Roughly like this:
SELECT B.*
FROM
(select user_id, max(record_date) max_date from mytable group by user_id) A
join
mytable B
on A.user_id = B.user_id and A.max_date = B.record_date
SELECT datatable.* FROM
mytable AS datatable
INNER JOIN (
SELECT user_id,max(record_date) AS max_record_date FROM mytable GROUP BS user_id
) AS selectortable ON
selectortable.user_id=datatable.user_id
AND
selectortable.max_record_date=datatable.record_date
in some SQLs you might need
SELECT MAX(user_id), ...
in the selectortable view instead of simply SELECT user_id,...
The definition of maximum: there is no larger(or: "more recent") value than this one. This naturally leads to a NOT EXISTS query, which should be available in any DBMS.
SELECT user_id, amount
FROM mytable mt
WHERE mt.user_id = $user
AND NOT EXISTS ( SELECT *
FROM mytable nx
WHERE nx.user_id = mt.user_id
AND nx.record_date > mt.record_date
)
;
BTW: your table definition allows more than one record to exist for a given {id,date}, but with different amounts. This query will return them all.