Find users, which are logged on the same Car - mysql

I have table with Columns:
---------------------------+---------+----------------------------+--------+
LogIn | CarNr |LogOut | UserID |
---------------------------+---------+----------------------------+--------+
2017-11-18-18.00.56.167000 | 7457518 | 2017-11-18-18.01.22.000000 | u39 |
2017-11-18-18.01.10.443000 | 7456618 | 2017-11-18-18.01.22.000000 | u2 |
2017-11-18-18.01.25.361000 | 7456586 | 2017-11-18-18.01.29.000000 | u64 |
2017-11-18-18.01.32.008000 | 7456612 | 2017-11-18-18.01.49.000000 | u17 |
2017-11-18-18.01.34.185000 | 7456257 | 2017-11-18-18.01.43.000000 | u2 |
2017-11-18-18.01.49.247000 | 7456345 | 2017-11-18-18.02.16.000000 | u64 |
----------------------------+---------+----------------------------+---------+
In fact, the data is much more.
Is there any way to find all users which are logged in the same CarNr within one Minute?
I need SQL-Query to find these users.

Try like this;
SQL Server
select CarNr, DATEADD(ms, -DATEPART(ms, LogIn), LogIn) from Table
group by CarNr, DATEADD(ms, -DATEPART(ms, LogIn), LogIn) having count(*) > 1
MySQL
select CarNr, DATE_ADD(LogIn, INTERVAL(-MICROSECOND(LogIn)) MICROSECOND) from Table
group by CarNr, DATE_ADD(LogIn, INTERVAL(-MICROSECOND(LogIn)) MICROSECOND) having count(*) > 1
Just Group LogIn datetime by subtracting milliseconds.

Related

Select value from table sorted by a certain order from another table

I want to select value from table sorted by a certain order.
I have a table called test that looks like this:
| date | code | value |
+----------+-----------+----------+
| 20050104 | 000005.SZ | -6359.19 |
| 20050104 | 600601.SH | -7876.34 |
| 20050104 | 600602.SH | -25693.3 |
| 20050104 | 600651.SH | NULL |
| 20050104 | 600652.SH | -15309.9 |
...
| 20050105 | 000005.SZ | -4276.28 |
| 20050105 | 600601.SH | -3214.56 |
...
| 20170405 | 000005.SZ | 23978.13 |
| 20170405 | 600601.SH | 32212.54 |
Right now I want to select only one date, say date = 20050104, and then sort the data by a certain order (the order that each stock was listed in the stock market).
I have another table called stock_code which stores the correct order:
+---------+-----------+
| code_id | code |
+---------+-----------+
| 1 | 000002.SZ |
| 2 | 000004.SZ |
| 3 | 600656.SH |
| 4 | 600651.SH |
| 5 | 600652.SH |
| 6 | 600653.SH |
| 7 | 600654.SH |
| 8 | 600602.SH |
| 9 | 600601.SH |
| 10 | 000005.SZ |
...
I want to sorted the selected data by stock_code(code_id), but I don't want to use join because it takes too much time. Any thoughts?
I tried to use field but it gives me an error, please tell me how to correct it or give me an even better idea.
select * from test
where date = 20050104 and code in (select code from stock_code order by code)
order by field(code, (select code from stock_code order by code));
Error Code: 1242. Subquery returns more than 1 row
You told us that you don't want to join because it takes too much time, but the following join query is probably the best option here:
SELECT t.*
FROM test t
INNER JOIN stock_code sc
ON t.code = sc.code
WHERE t.date = '20050104'
ORDER BY sc.code_id
If this really runs slowly, then you should check to make sure you have indices setup on the appropriate columns. In this case, indices on the code columns from both tables as well as an index on test.date should be very helpful.
ALTER TABLE test ADD INDEX code_idx (code)
ALTER TABLE test ADD INDEX date_idx (date)
ALTER TABLE code ADD INDEX code_idx (code)

MySQL Query isn't showing most recent username

I have a special problem with my statistics query. I want to get the most recent username, duration, and connection count of every client that connected to a server. This is the query:
SELECT name, SUM(duration) AS time, COUNT(auth) AS connections
FROM analytics
WHERE duration IS NOT NULL
GROUP BY auth
ORDER BY time DESC;
The problem is that they query isn't showing the most recent username. It takes the first entrance of the client (identified by auth) in the database even if the client changed their username already.
Is there a way to get the most recent username of the client in the query above without slowing it down a lot?
Example Table:
| id | auth | name | duration |
|----|------|------|----------|
| 1 | u123 | Fire | 50 |
| 2 | u555 | Dan | 20 |
| 3 | u123 | Ice | 30 |
What I get:
| name | time | connections |
|------|----------|-------------|
| Fire | 80 | 2 |
| Dan | 20 | 1 |
What I want
| name | time | connections |
|------|----------|-------------|
| Ice | 80 | 2 |
| Dan | 20 | 1 |
I assume that you want most recent auth order by ID coz there is no other data to get it.
SELECT A.name, B.time, B.connections
FROM analytics AS A
INNER JOIN
(
SELECT auth, MAX(ID) AS MAXID, SUM(duration) AS time, COUNT(auth) as connections
FROM analytics B
WHERE duration IS NOT NULL
GROUP BY auth
) AS B
ON A.auth = B.auth AND A.ID = B.MAXID
If you have a TimeStamp column for the recent registred user.
you can get it using the max()
select * from database where registered like (select max(registered) from database;
I wish it will help. Just analyze the idea.

Return one record with multiple entries on the same date

I have a table that looks like
| OPDNo |DispensedDate | Drugname | CreatedBy|
| 011650/16 | 6/29/2016 |folic acid | admin |
| 011650/16 | 6/29/2016 |multivite | admin |
| 011650/16 | 6/21/2016 |fersolate | asah |
| 011650/16 | 6/21/2016 |amoxicyllin| eantwi |
| 025343/13 | 5/23/2016 |aspirin | emelia |
And i want the record selection to be like this when i query like
select * from dispensary where OPNo='011650/16'
| OPDNo |DispensedDate | DrugName | CreatedBy|
| 011650/16 | 6/29/2016 |folic acid| admin |
| 011650/16 | 6/21/2016 |fersolate | asah |
That is I want only one record for every OPNo on a particular date. If an OPDNo has one or more entries on the same date, then the query should return only entry. Probably the first entry for each date if an OPDNo has more entries on that particular date.
You can try this...
select * from dispensary do
where do.Drugname in (select max(Drugname) from dispensary di
where di.OPDNo = do.OPDNo
and di.DispensedDate = do.DispensedDate)
and do.OPDNo = '011650/16'
but keep in mind that the result will not be the first drug
Try this
select * from (select * from dispensary order by DispensedDate desc) as a where OPNo='011650/16'
group by DispensedDate;
If your DispensedDate is of type "DateTime" then you can try below
select * from (select * from dispensary order by DispensedDate desc) as a where OPNo='011650/16'
group by date_format(DispensedDate, '%m/%d/%Y');
Let me know if this is working.

Retrieve all not logged in users from mysql tables (SQL query)

I have 2 tables listed below:
+-------------+-----------+--------------+-------------------------------+
| v3_customer |
+-------------+-----------+--------------+-------------------------------+
| customer_id | firstname | lastname | email |
+-------------+-----------+--------------+-------------------------------+
| 1 | Piet | Pizza | piet.pizza#example.com |
| 2 | Klaas | Hein | klaas.hein#example.com |
| 3 | Henk | Crowdcontrol | henk.crowdcontrol#example.com |
+-------------+-----------+--------------+-------------------------------+
+-------------+-------------+---------------+
| v3_customer_activity |
+-------------+-------------+---------------+
| activity_id | customer_id | key |
+-------------+-------------+---------------+
| 1 | 1 | login |
| 2 | 1 | order_account |
| 3 | 2 | login |
+-------------+-------------+---------------+
What i want is to select all customers which haven't logged in yet (note the login key in v3_customer_activity). So in this case that would be the customer with customer_id: 3
I'm using a mysql database.
I have tried using the following query:
SELECT DISTINCT v3_customer.customer_id, v3_customer.firstname, v3_customer.lastname, v3_customer.email FROM `v3_customer` JOIN v3_customer_activity ON v3_customer.customer_id = v3_customer_activity.customer_id WHERE v3_customer.customer_id != (SELECT v3_customer_activity.customer_id FROM v3_customer_activity)
In the hope it would iterate between the rows found in the subquery.
This resulted in an error telling me a subquery may not contain multiple rows.
TL;DR
What I want is to retrieve every customer from v3_customer who is not listed in the table v3_customer_activity
Try this:
select v3_customer.* from v3_customer
left join v3_customer_activity on v3_customer.customer_id=v3_customer_activity.customer_id
where v3_customer_activity.customer_id is null;
Left join v3_customer table with v3_customer_activity and filter records which are not matched.
select v3_customer.* from v3_customer
where v3_customer.customer_id not in (SELECT v3_customer_activity.customer_id FROM v3_customer_activity)

MySQL: GROUP BY with custom hierarchical functionality

I've got a permission/privileges - table looking like this:
+----+----------+----------+------+-------+
| id | name | usertype | read | write |
+----+----------+----------+------+-------+
| 1 | test | A | 0 | 0 |
| 2 | test | MU | 1 | 1 |
| 3 | test | U | 1 | 1 |
| 4 | apple | A | 1 | 1 |
| 5 | apple | MU | 1 | 0 |
| 6 | apple | U | 0 | 0 |
| 7 | flower | A | 0 | 0 |
| 8 | flower | MU | 0 | 0 |
| 9 | flower | U | 1 | 1 |
+----+----------+----------+------+-------+
there are 3 usertypes: A (admin), MU (maintenance user), U (standard user)
the usertypes are hierarchical: A > MU > U
(the usertypes are saved as CHAR(2) in the database, and unfortunately I can't change that)
now i want to build a query which implements the hierarchical logic of my usertypes.
e.g. usertype 'A' got no permission to read or write on stuff with the name 'test', thus usertypes 'MU' AND 'U' also should have no permission for that and their read = 1 and write = 1 should be ignored.
I know which usertype is currently logged in.
I somehow have to check for the minimum of read/write rights to the name for all hierarchical predecessors, i guess. but i don't know how to check that since usertype is not a number field.
this is what I've tried so far:
SELECT
name,
MIN(read),
MIN(write),
CASE
WHEN usertype = 'A' THEN 0
ELSE (CASE
WHEN usertype = 'WU' THEN 1
ELSE 2
END)
END userval
FROM
permissions
-- WHERE usertype <= :current_usertype
GROUP BY name
this seems to work, but i don't know how i can get my condition WHERE usertype <= :current_usertype working, so a usertype down in the hierarchy can't get more privileges on a name than a "higher" usertype.
any ideas?
thanks in advance!
This is how I solved my problem:
1. I added another table "permission_groups" to the database:
+----+----------+--------+
| id | usertype | value |
+----+----------+--------+
| 1 | A | 100 |
| 2 | MU | 20 |
| 3 | U | 10 |
+----+----------+--------+
2. Then I joined this table to my original table "permissions" which i showed in my question:
here i get the value of my "permission_groups" table with a subquery. this value symbolizes the hierarchical order of my different usertypes.
SELECT
perm.name,
MIN(perm.`read`),
MIN(perm.`write`),
group .value
FROM
permissions perm
LEFT JOIN permission_groups group ON group.usertype = perm.usertype
WHERE
group.value >= (SELECT value from permission_groups WHERE usertype = :current_usertype)
GROUP BY perm.name
:current_usertype is a PDO parameter in my case, which is replaced by the usertype of the current user.