I have over 1100+ records in my people (table) and i would like to filter those who are under a specific place (table) record and would update a newly inserted column value named people_identifier_num of people table.
Place table
id name desc
1 Place 1 some description.
2 Place 2 some description..
3 Place 3 some description...
People table
id name place_id people_identifier_num
1 People 1 1 null
2 People 2 1 null
3 People 3 2 null
4 People 4 2 null
5 People 5 2 null
6 People 6 2 null
7 People 7 3 null
... ... ... ....
1100 People 1100 2 null
Now i would like to assign a pin (people_identifier_num) to every person that belongs to a particular place which begin with value 1 and so on..
E.g.
id name place_id people_identifier_num
3 People 3 2 1
4 People 4 2 2
5 People 5 2 3
6 People 6 2 4
... ... ... ....
E.g.
id name place_id people_identifier_num
1 People 1 1 1
2 People 2 1 2
... ... ... ....
My current solution is to filter people by place and sort it by name alphabetically. However how can we write a SQL script that loop each filtered record and assign the pin value starting from 1 and so on?
You can use rank query to assign pin no. to each people according to their place
update people
join (
select p.id,place_id,name,
case when #place = place_id then #row:= #row +1 else #row:= 1 end rank,
#place:= place_id
from (
select * from people,(select #place:=null,#row:=1) t order by place_id,name
) p
) p1
using(place_id,name)
set people_identifier_num = p1.rank;
Demo
Related
I have two tables DOCUMENT and SIGNATURES, like below
DOCUMENTS
doc_id doc_name
1 Contract
2 Lead
3 Invoice 1
4 Invoice 2
5 Payment 123
SIGNATURES
sig_id sig_doc_id signature_name
1 1 Paul
2 2 Mark
3 1 Chew
4 2 Paul
5 3 John
6 3 Derek
7 3 Silvan
8 5 Roden
And I'm try to get last signature name.
EXPECTED OUTPUT
doc_id doc_name signature_name
1 Contract Chew
2 Lead Paul
3 Invoice 1 Silvan
4 Invoice 2 < empty because we not have signature
5 Payment 123 Roden
I have a SQL FIDDLE with database and query, but when run search no record has found.
http://sqlfiddle.com/#!9/b98474/3
Here my query
SELECT docs.*, sign.*
FROM cnt_man_docs docs
INNER JOIN cnt_man_doc_signatures sign ON docs.cnt_man_doc_id = sign.cnt_man_doc_signature_doc_id
WHERE sign.cnt_man_doc_signature_id =
(SELECT MAX(cnt_man_doc_signature_id)
FROM cnt_man_doc_signatures
WHERE sign.cnt_man_doc_signature_id = docs.cnt_man_doc_id)
A simple method is a correlated subquery:
select d.*,
(select s.signature_name
from signatures s
where s.sig_doc_id = d.doc_id
order by s.sig_id desc
limit 1
) as signature_name
from documents d;
With an index on signatures(doc_id, sig_id desc, signature_name) this is probably the fastest method as well.
How to insert rows for each of the type column? If there is two type, type 1 and type 2, then I need to insert two rows and also need to change the order and id value for whole table.
current status:
CHOICE Table
id choice type order
1 AA 1 1
2 BB 1 2
3 CC 1 3
4 AAA 2 4
5 BBB 2 5
6 CCC 2 6
7 DDD 2 7
Required updated table:
Now i wan to insert choice "000" for each type. The updated table will be look like bellow. How can I achieve this?
updated CHOICE Table
id choice type order
1 000 1 1
2 AA 1 2
3 BB 1 3
4 CC 1 4
5 000 2 5
6 AAA 2 6
7 BBB 2 7
8 CCC 2 8
9 DDD 2 9
here, id and order column serialized again.
The actual table is too big, so I cannot insert by edit. Please help for this complex query. I have no clue to solve this.
Use insert . . . select to insert the rows:
insert into choice (choice, type)
select distinct '000', type
from choice;
This assumes that id is automatically assigned (and it will be different from your example).
However, it looks like you want to update the order as well. For this, I would suggest an update:
update choice c join
(select c2.*,
row_number() over (partition by choice order by (order is null) desc, order) as new_order
from choice c2
) c2
on c.id = c2.id
set c.order = c2.new_order;
As an editorial comment, order is a very bad choice for a column name because it is a SQL keyword.
I have a database with a table called BOOKINGS containing the following values
main-id place-id start-date end-date
1 1 2018-8-1 2018-8-8
2 2 2018-6-6 2018-6-9
3 3 2018-5-5 2018-5-8
4 4 2018-4-4 2018-4-5
5 5 2018-3-3 2018-3-10
5 1 2018-1-1 2018-1-6
4 2 2018-2-1 2018-2-10
3 3 2018-3-1 2018-3-28
2 4 2018-4-1 2018-4-6
1 5 2018-5-1 2018-5-15
1 3 2018-6-1 2018-8-8
1 4 2018-7-1 2018-7-6
1 1 2018-8-1 2018-8-18
1 2 2018-9-1 2018-9-3
1 5 2018-10-1 2018-10-6
2 5 2018-11-1 2018-11-5
2 3 2018-12-1 2018-12-25
2 2 2018-2-2 2018-2-19
2 4 2018-4-4 2018-4-9
2 1 2018-5-5 2018-5-23
What I need to do is for each main-id I need to find the largest total number of days for every place-id. Basically, I need to determine where each main-id has spend the most time.
This information must then be put into a view, so unfortunately I can't use temporary tables.
The query that gets me the closest is
CREATE VIEW `MOSTTIME` (`main-id`,`place-id`,`total`) AS
SELECT `BOOKINGS`.`main-id`, `BOOKINGS`.`place-id`, SUM(DATEDIFF(`end-date`, `begin-date`)) AS `total`
FROM `BOOKINGS`
GROUP BY `BOOKINGS`.`main-id`,`RESERVATION`.`place-id`
Which yields:
main-id place-id total
1 1 24
1 2 18
1 5 5
2 1 2
2 2 20
2 4 9
3 1 68
3 2 24
3 3 30
4 1 5
4 2 10
4 4 1
5 1 19
5 2 4
5 5 7
What I need is then the max total for each distinct main-id:
main-id place-id total
1 1 24
2 2 20
3 1 68
4 2 10
5 1 19
I've dug through a large amount of similar posts that recommend things like self joins; however, due to the fact that I have to create the new field total using an aggregate function (SUM) and another function (DATEDIFF) rather than just querying an existing field, my attempts at implementing those solutions have been unsuccessful.
I am hoping that my query that got me close will only require a small modification to get the correct solution.
Having hyphen character - in column name (which is also minus operator) is a really bad idea. Do consider replacing it with underscore character _.
One possible way is to use Derived Tables. One Derived Table is used to determine the total on a group of main id and place id. Another Derived Table is used to get maximum value out of them based on main id. We can then join back to get only the row corresponding to the maximum value.
CREATE VIEW `MOSTTIME` (`main-id`,`place-id`,`total`) AS
SELECT b1.main_id, b1.place_id, b1.total
FROM
(
SELECT `main-id` AS main_id,
`place-id` AS place_id,
SUM(DATEDIFF(`end-date`, `begin-date`)) AS total
FROM BOOKINGS
GROUP BY main_id, place_id
) AS b1
JOIN
(
SELECT dt.main_id, MAX(dt.total) AS max_total
FROM
(
SELECT `main-id` AS main_id,
`place-id` AS place_id,
SUM(DATEDIFF(`end-date`, `begin-date`)) AS total
FROM BOOKINGS
GROUP BY main_id, place_id
) AS dt
GROUP BY dt.main_id
) AS b2
ON b1.main_id = b2.main_id AND
b1.total = b2.max_total
MySQL 8+ solution would be utilizing the Row_Number() functionality:
CREATE VIEW `MOSTTIME` (`main-id`,`place-id`,`total`) AS
SELECT b.main_id, b.place_id, b.total
FROM
(
SELECT dt.main_id,
dt.place_id,
dt.total
ROW_NUMBER() OVER (PARTITION BY dt.main_id
ORDER BY dt.total DESC) AS row_num
FROM
(
SELECT `main-id` AS main_id,
`place-id` AS place_id,
SUM(DATEDIFF(`end-date`, `begin-date`)) AS total
FROM BOOKINGS
GROUP BY main_id, place_id
) AS dt
GROUP BY dt.main_id
) AS b
WHERE b.row_num = 1
I have a MySQL table called personxmessage, extracted from emails. It has three fields, id (primary key), MessageID, and PersonID. For each message referenced by MessageID, there are two or more records, each with a PersonID for a person who was included in the email (i.e. in sender, sent to, or cc).
I want to query this table to get a link list showing all the people who were linked to a given PersonID=XXXX, and the links between them defined by being included on the emails that include XXXX, preferably including a weight on the links showing the number of occurrences. Another way of saying this, in graph terminology, is I'm trying to get the neighborhood of XXXX. For example, for entries like
MID PID
1 1
1 2
1 3
2 1
2 2
3 1
3 3
3 4
For PersonID 1 I would like to get link list
P1 P2 Count
1 1 3
1 2 2
1 3 2
1 4 1
2 3 1
3 4 1
Is it possible to do this with some kind of self-join? If so what query would I use? I have done some simpler joins (for example to get the star-graph of XXXX and other PersonIDs that are with XXXX on emails) but this one is over my head.
You can use GROUP_CONCAT do to something sort of like that. It's not a table but a result set of the related pids per mid.
select mid, group_concat(distinct pid order by pid separator ', ') as related_ppl
from personxmessage
group by mid;
result
mid related_ppl
1 1, 2, 3
2 1, 2
3 1, 3, 4
I think this is what you're looking for:
select p.pid as pid1, pp.pid as pid2, count(*) as cnt
from personxmessagep
left join personxmessagepp
on p.mid = pp.mid
and p.pid < pp.pid
group by p.pid, pp.pid;
result
pid pid2 cnt
1 2 2
1 3 2
1 4 1
2 1
2 3 1
3 1
3 4 1
4 1
Suppose I have a table like so,
unqiue_data int(10),
not_unique_data int (10)
unique_data not_unique_data
1 1
2 1
3 2
4 2
5 2
select * from some_table order by not_unique_data DESC;
What I need to do, is randomize this SELECT query, but in a very two particular ways that I just can't figure out how to do. Firstly, I want unique_data randomized, so that the SELECT query could return something like (randomly):
unique_data not_unique_data
2 1
1 1
4 2
3 2
5 2
The second requirement I have is that, unique_data appears multiple times, but in a very specific order.
In an ideal world, I need is so that it could return something like
unique_data not_unique_data
4 2
3 2
5 2
1 1
2 1
3 2
5 2
4 2
2 1
1 1
5 2
4 2
3 2
What I mean by this is, I need it so that each unique_data (4,3,5), (3,5,4), (5,4,3) The first number of each set appears only once while still being ordered by not_unique_data.
How to do this?
Well for this problem you have to make sure that 100 products related to a product
how many of them have appeared for that product
how many of them will be appeared for that product
We can use a temporary table to do so
SELECT unique_data, not_unique_data, 0
INTO temp_newtable
FROM some_table
ORDER BY RAND()
Now we will get a randomly organized table and by default seen=0 (seen to know it has been appeared for that product or not)
unique_data not_unique_data seen
4 2 1
3 2 1
5 2 0
1 1 0
2 1 0
3 2 1
So whenever some product related to product appear on page you need to update seen column to 1, when you are out of this table truncate and generate random data for usage again
I think you are looking for this https://stackoverflow.com/a/3990479/2552551
SELECT * FROM
(
SELECT * FROM some_table
ORDER BY not_unique_data DESC
LIMIT 100
) T1
ORDER BY RAND()