Needed aid with complicated MySQL query - very narrow scope - mysql

Here are my TABLES described and their contents:
users:
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| public_key_path | varchar(100) | NO | | NULL | |
| email | varchar(50) | NO | | NULL | |
| pbox | varchar(50) | YES | UNI | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
contents:
+----+-------------------+----------------------+--------+
| id | public_key_path | email | pbox |
+----+-------------------+----------------------+--------+
| 33 | /path/to/pubkey1/ | FirstUser#email.com | Pbox01 |
| 34 | /path/to/pubkey2/ | SecondUser#email.com | Pbox02 |
| 35 | /path/to/pubkey3/ | ThirdUser#email.com | Pbox03 |
+----+-------------------+----------------------+--------+
files:
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| file_path | varchar(100) | NO | UNI | NULL | |
| owner_id | int(11) | NO | MUL | NULL | |
+-----------+--------------+------+-----+---------+----------------+
contents:
+-----+-----------------+----------+
| id | file_path | owner_id |
+-----+-----------------+----------+
| 104 | /path/to/file1/ | 33 |
| 105 | /path/to/file2/ | 34 |
| 106 | /path/to/file3/ | 35 |
| 107 | /path/to/file4/ | 33 |
| 108 | /path/to/file5/ | 33 |
| 109 | /path/to/file6/ | 34 |
+-----+-----------------+----------+
encrypted_symmetric_keys:
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| key_path | varchar(100) | YES | UNI | NULL | |
| file_id | int(11) | NO | MUL | NULL | |
| user_id | int(11) | NO | MUL | NULL | |
+----------+--------------+------+-----+---------+----------------+
contents:
+-----+---------------------+---------+---------+
| id | key_path | file_id | user_id |
+-----+---------------------+---------+---------+
| 106 | /path/to/key1forU1/ | 104 | 33 |
| 107 | /path/to/key2forU2/ | 105 | 34 |
| 108 | /path/to/key3forU3/ | 106 | 35 |
| 109 | /path/to/key4forU1/ | 107 | 33 |
| 110 | /path/to/key5forU1/ | 108 | 33 |
| 111 | /path/to/key6forU2/ | 109 | 34 |
| 112 | /path/to/key3forU1/ | 106 | 33 |
| 113 | /path/to/key2forU1/ | 105 | 33 |
| 114 | /path/to/key6forU1/ | 109 | 33 |
+-----+---------------------+---------+---------+
This is a newbie database for a server that stores filepaths that are encrypted with encrypted symmetric keys(ESKs).
If there is key_path /path/to/key1forU1/ that means that the key is stored for file1 for user1.
I need a query that, when given file_path (ex. "/path/to/file1/") lists all users that have access to this file.
Let me know if you need any more information, I'll provide it immediately.
I know that this is a very localized question, but I've been thinking for more than an hour about that now and I'm having horrible problems with wrapping my head around it.
Thank you very much in advance.
EDIT:
My final set of data I need is, when given
'/path/to/file1/'
would return
FirstUser#email.com
But when given for example
/path/to/file2/'
would return
FirstUser#email.com
SecondUser#email.com
because

I think this is what you are looking for
as this will give you all email that are using file_path = '/path/to/file6/' except the owner's email
SELECT su.email
FROM encrypted_symmetric_keys AS c
INNER JOIN users AS su ON su.id = c.user_id
INNER JOIN files AS f ON f.id = c.file_id AND f.owner_id <> c.user_id
WHERE f.file_path = '/path/to/file6/'

Related

How do I prevent combinations or permutaions in a joining table?

I have the following tables in MySQL Workbench:
MdV, MdV_has_Chain and Chain.
describe MdV
+------------+--------------+------+-----+-------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------+-------+
| MdVID | varchar(255) | NO | PRI | NULL | |
| Source | longtext | YES | | NULL | |
| Chains | int unsigned | NO | | 0 | |
| CampaignID | varchar(255) | NO | MUL | No_Campaign | |
+------------+--------------+------+-----+-------------+-------+
describe MdV_has_Chain
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| MdVID | varchar(255) | NO | PRI | NULL | |
| ChainID | varchar(255) | NO | PRI | NULL | |
| Chain_Num | int unsigned | NO | | NULL | |
+-----------+--------------+------+-----+---------+-------+
describe Chain
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| ChainID | varchar(255) | NO | PRI | NULL | |
| Positions | int unsigned | NO | | 0 | |
| VectorID | varchar(255) | NO | | NULL | |
+-----------+--------------+------+-----+---------+-------+
Here they are in the EER diagram.
Currently the tables of interest hold the following mock data:
select * from mdv;
+-------------+-----------------+--------+-------------+
| MdVID | Source | Chains | CampaignID |
+-------------+-----------------+--------+-------------+
| ITS058-M152 | | 1 | C7 |
| ITS058-M182 | | 2 | No_Campaign |
| ITS058-M244 | Rational Design | 1 | C16 |
| ITS058-M253 | Rational Design | 2 | C17 |
| ITS058-M258 | | 1 | No_Campaign |
| TEST | | 0 | No_Campaign |
+-------------+-----------------+--------+-------------+
select * from mdv_has_chain;
+-------------+------------+----------------+
| MdVID | ChainID | chain_position |
+-------------+------------+----------------+
| ITS058-M152 | ITS058-Ch1 | 1 |
| ITS058-M182 | ITS058-Ch2 | 1 |
| ITS058-M182 | ITS058-Ch3 | 2 |
| ITS058-M244 | ITS058-Ch4 | 1 |
| ITS058-M253 | Ch1 | 2 |
| ITS058-M253 | ITS058-Ch5 | 1 |
| ITS058-M258 | ITS058-Ch6 | 1 |
+-------------+------------+----------------+
select * from chain;
+------------+-----------+-------------+
| ChainID | Positions | VectorID |
+------------+-----------+-------------+
| Ch1 | 2 | T343 |
| ITS058-Ch1 | 7 | ITS058-V240 |
| ITS058-Ch2 | 7 | ITS058-V278 |
| ITS058-Ch3 | 1 | R208 |
| ITS058-Ch4 | 6 | ITS058-V352 |
| ITS058-Ch5 | 7 | ITS058-V361 |
| ITS058-Ch6 | 6 | ITS058-V366 |
+------------+-----------+-------------+
To see what chains each MdV has I used the following query:
select mdv.mdvid, group_concat(mdv_has_chain.chainid order by mdv_has_chain.chain_num) as chainid, group_concat(mdv_has_chain.chain_num order by mdv_has_chain.chain_num) as chain_position from mdv inner join mdv_has_chain on mdv.mdvid = mdv_has_chain.mdvid group by mdv_has_chain.mdvid
+-------------+-----------------------+----------------+
| mdvid | chainid | chain_position |
+-------------+-----------------------+----------------+
| ITS058-M152 | ITS058-Ch1 | 1 |
| ITS058-M182 | ITS058-Ch2,ITS058-Ch3 | 1,2 |
| ITS058-M244 | ITS058-Ch4 | 1 |
| ITS058-M253 | ITS058-Ch5,Ch1 | 1,2 |
| ITS058-M258 | ITS058-Ch6 | 1 |
+-------------+-----------------------+----------------+
I was wondering how I would prevent same ChainIds or a combination of them from being entered to a different MdVID? For example how would I prevent the following insert from working:
insert into mdv_has_chain (mdvid, chainid, chain_num) values ("TEST", "ITS058-Ch2", 2), ("TEST", "ITS058-Ch3", 1)
ITS058-M182 already has those ChainIDs, but in different positions. Note that an MdV can have from 1 to N chains. Similarly, how would I allow permutations of ChainIds at different positions, but prevent entries with the same positions from being entered? I don't intend on implementing both things at once. I just wanted to know how I would achieve either individually.
Thank you for you time. Any help is appreciated.

fill at once data null on table sql

I have table transaksi:
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(150) | YES | | NULL | |
| price | int(11) | YES | | NULL | |
| type | int(11) | YES | | NULL | |
+-------------+--------------+------+-----+---------+-------+
and have data (I fill in the data with insert into transaksi (name,price,type) select name,price,type from store)
+-----------+--------------------------+---------+-------+
| id | name | price | Type |
+-----------+--------------------------+---------+-------+
| NULL | Pants | 79 | 9 |
| NULL | Cup | 38 | 7 |
| NULL | Shoes | 21 | 1 |
| NULL | Hat | 11 | 5 |
| NULL | Pulpen | 39 | 2 |
+___________|__________________________|_________|_______|
How to fill "NULL" data at once in ID ?

Adding (results of a query) to an existing table

So i have the following problem. I have 2 tables (Users: 100 rows and geo-zipcodes: 450k rows) and I want to update my users table to display the lon and lat if the zipcode is filled in. When it's not filled in i want the lon/lat to display NULL. How do I achieve this?
I do this in MySQL using the standard provided MySQL workbench.
+CURRENT SITUATION----+------+
| id | zipcode | lon | lat |
+----+---------+------+------+
| 88 | 3531EK | NULL | NULL |
| 89 | 5691JN | NULL | NULL |
| 90 | 5701NR | NULL | NULL |
| 91 | 3531EK | NULL | NULL |
| 92 | 5691JN | NULL | NULL |
| 93 | NULL | NULL | NULL |
| 94 | NULL | NULL | NULL |
| 95 | NULL | NULL | NULL |
| 96 | NULL | NULL | NULL |
| 97 | NULL | NULL | NULL |
+----+---------+------+------+
+FUTURE SITUATION------------------+-----------------+
| id | zipcode | lat | lon |
+-----+---------+------------------+-----------------+
| 583 | NULL | NULL | NULL |
| 632 | NULL | NULL | NULL |
| 797 | 4194WD | 51.8724978062918 | 5.2758839816285 |
| 812 | 9723ZT | 53.2067353295688 | 6.5886266741127 |
| 782 | 5617BD | 51.4471593854488 | 5.4566869544855 |
| 799 | NULL | NULL | NULL |
| 800 | 5623ET | 51.4618395108795 | 5.4733910341403 |
| 179 | 5709BN | 51.4752182995384 | 5.7022349534995 |
| 112 | 5701CN | 51.4759330063412 | 5.6780783810570 |
| 90 | 5701NR | 51.4775509176254 | 5.6576320175919 |
+-----+---------+------------------+-----------------+
In MySQL, you can do this with a join:
update users u join
zipcodes z
on u.zipcode = z.zipcode
set u.lat = z.lat, u.lon = z.lon;
However, I don't see why this is necessary. Why not just look up the coordinates using the zip code table when you need it? There might be good reasons -- for instance, you might have other sources of coordinates. But if the zip code is the only source, then there is no need to store the same information in two places.

How To select Query

I have a table view named as tes.
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id_oba | int(11) | NO | | NULL | |
| nama_obat | varchar(120) | NO | | NULL | |
| satuan | varchar(20) | YES | | NULL | |
| stok_awal | int(5) | YES | | NULL | |
| persediaan | int(5) | YES | | NULL | |
| nama_suplier | varchar(30) | NO | | NULL | |
| pemakaian | int(4) | NO | | NULL | |
| tanggal | date | YES | | NULL | |
+--------------+--------------+------+-----+---------+-------+
When I execute:
select id_oba, nama_obat, satuan, stok_awal, sum(pemakaian) AS pemakaian, persediaan,
from tes group by id_oba;
I get this result:
+--------+-----------+--------+-----------+-----------+------------+
| id_oba | nama_obat | satuan | stok_awal | pemakaian | persediaan |
+--------+-----------+--------+-----------+-----------+------------+
| 1 | Paramex | Botol | 30 | 40 | 5 |
| 2 | Oskadon | Botol | 30 | 41 | 27 |
| 3 | Lindon | Botol | 31 | 30 | 4 |
+--------+-----------+--------+-----------+-----------+------------+
How can I modify my query to get the result like this?
+--------+-----------+--------+-----------+-----------+------------+-------+
| id_oba | nama_obat | satuan | stok_awal | pemakaian | persediaan | total |
+--------+-----------+--------+-----------+-----------+------------+-------+
| 1 | Paramex | Botol | 30 | 40 | 5 | 45 |
| 2 | Oskadon | Botol | 30 | 41 | 27 | 67 |
| 3 | Lindon | Botol | 31 | 30 | 4 | 34 |
+--------+-----------+--------+-----------+-----------+------------+-------+
Please help me with my problem.
Thanks.
Change like this
select id_oba, nama_obat, satuan, stok_awal, sum(pemakaian) AS pemakaian,
persediaan,(sum(pemakaian)+persediaan) as total from tes group by id_oba;

rows missing with group by added

this is probably something very noob of me
i have the following table
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| from_id | int(11) | YES | MUL | NULL | |
| to_id | int(11) | YES | MUL | NULL | |
| reply_cost | int(5) | YES | | 0 | |
| date | timestamp | YES | | NULL | |
| body | text | YES | | NULL | |
| read_ | char(1) | YES | | 0 | |
| trash | tinyint(1) | YES | MUL | 0 | |
| trashDate | datetime | YES | | NULL | |
| ip_address | varchar(20) | YES | | NULL | |
+------------+-------------+------+-----+---------+----------------+
a select like
select id,from_id,to_id,date from mail where to_id='100' order by id desc limit 50;
returns
+----------+---------+-------+---------------------+
| id | from_id | to_id | date |
+----------+---------+-------+---------------------+
| 30071061 | 142 | 100 | 2013-08-15 04:39:56 |
| 30070785 | 282 | 100 | 2013-08-15 02:29:00 |
| 30064666 | 282 | 100 | 2013-08-14 16:10:39 |
| 30042809 | 458582 | 100 | 2013-08-12 15:50:45 |
| 30042560 | 458582 | 100 | 2013-08-12 15:28:39 |
| 30042557 | 458582 | 100 | 2013-08-12 15:28:22 |
| 30022845 | 458582 | 100 | 2013-08-10 17:32:40 |
| 30022834 | 458582 | 100 | 2013-08-10 17:31:22 |
| 30018276 | 458582 | 100 | 2013-08-10 06:09:27 |
| 30018275 | 458582 | 100 | 2013-08-10 06:09:00 |
but a select like this
select id,from_id,to_id,date from mail where to_id='100' group by from_id order by id desc limit 50;
outputs like this (from_id 282 is missing)
+----------+---------+-------+---------------------+
| id | from_id | to_id | date |
+----------+---------+-------+---------------------+
| 30017678 | 142 | 100 | 2013-08-10 01:56:38 |
| 29928935 | 189638 | 100 | 2013-07-31 18:33:01 |
| 29894382 | 458582 | 100 | 2013-07-27 22:15:53 |
| 29883054 | 409699 | 100 | 2013-07-26 15:22:35 |
any idea how this can be avoided ?
EDIT: forgot to mention, the goal is to return only one row per from_id.
What about the query
select id,from_id,to_id,date from mail where to_id='100' order by id, from_id desc limit 50;
That should work, hopefully.