sql - get parentID with or without child in self refrenced table - mysql

Here is my table's (events) content. eventID is "primary key" and parentID is "foreign key" with references to events(eventsID)
self referenced table :
eventID eventName parentID appFK
1 evt1 null 2
2 evt2 1 1
3 evt3 1 1
4 evt4 null 3
5 evt5 8 3
6 evt6 null 4
7 evt7 null 1
8 evt8 null 1
and another table content (applications) like this :
appID appName
1 app1
2 app2
3 app3
4 app4
I'd like to fetch all eventIDs which are parents or not with a given appID. If a child has the given appID, i'd like to get his parentID and not himself. So the result is going to be like this with appID = 1 :
eventID eventName ParentID appFK
1 evt1 null 2 // parent event who has children with appID = 1
7 evt7 null 1 // event with no child and appID = 1
8 evt8 null 1 // parent event with appID = 1 and has a child
I tried lot of examples and read a lot of solutions here but i didn't find a problem like this. Can you help me to write the right SQL ?
thx.

Try this:
SELECT DISTINCT COALESCE(e2.eventID, e1.eventID),
COALESCE(e2.eventName, e1.eventName),
COALESCE(e2.appFK, e1.appFK)
FROM events AS e1
LEFT JOIN events AS e2 ON e1.parentID = e2.eventID AND e1.appFK = 1
WHERE (e1.appFK = 1 AND e1.parentID IS NULL) OR (e2.eventID IS NOT NULL)
The LEFT JOIN fetches parent records (e1.parentID = e2.eventID) of a child having appID = 1 (e1.appFK = 1).
The WHERE clause selects root records having appID = 1 and root records that are related to a child having appID = 1 (e2.eventID IS NOT NULL).
Demo here

Related

Codeigniter - left join tables

i have a table for my sql like this :
result_podium
id_result_podium
id_race
id_rider
position
point
and
result_dnf
id_result_dnf
id_race
id_rider
So what im trying to do is to join those two table and shown it as one, and here is the result and what i have tried so far :
Attempt 1 :
$this->db->select_sum('result_podium.point');
$this->db->select('riders.name AS rider_name, teams.name AS team_name');
$this->db->from('result_podium');
$this->db->join('riders','riders.id_rider = result_podium.id_rider');
$this->db->join('result_dnf','result_dnf.id_rider = riders.id_rider', 'left');
$this->db->join('teams','teams.id_team = riders.id_team');
$this->db->where('riders.is_deleted','0');
$this->db->order_by("SUM(result_podium.point) DESC");
$this->db->group_by(array('result_podium.id_rider','result_dnf.id_rider'));
$query = $this->db->get();
return $query->result();
And the result is something like this :
No
rider
point
1
Nick
10
2
A
5
3
D
5
4
CC
4
5
B
4
it managed to get data from table result_podium but not managed to join data from table result_dnf, and here is my another attempt :
Attempt 2 :
$this->db->select_sum('result_podium.point');
$this->db->select('result_dnf.*, riders.name AS rider_name, teams.name AS team_name');
$this->db->from('result_dnf');
$this->db->join('riders','riders.id_rider = result_dnf.id_rider');
$this->db->join('teams','teams.id_team = riders.id_team');
$this->db->join('result_podium','result_podium.id_rider = riders.id_rider', 'left');
$this->db->where('riders.is_deleted','0');
$this->db->order_by("SUM(result_podium.point) DESC");
$this->db->group_by(array('result_dnf.id_rider','result_podium.id_rider'));
and here is the result :
No
rider
point
1
A
5
2
D
5
3
B
4
4
CC
4
5
Bri
6
Brum
the point data forBri and Brum, is null because they came from result_dnf, but i did not managed to get Nick data from result_podium.
And here what i was expecting for the data to shown in my view :
No
rider
point
1
Nick
10
2
A
5
3
D
5
4
CC
4
5
B
4
5
Bri
6
Brum
is there a way to join those two table?, anyhelp is really appreciated thank you!.

SQLAlchemy query construction

I'm working with a Key model backed by Postgres that is a generic table to hold API keys:
class Key(Model):
__tablename__ = "keys"
id = Column(Integer, primarykey=True)
user_id = Column(Integer, ForeignKey("users.id"))
brokerage_id = Column(Integer, ForeignKey("brokerages.id"))
account_id = Column(Integer, ForeignKey("accounts.id"))
key = Column(String(128))
value = Column(String(128))
In the below example, user 2 has three keys. All three are associated with brokerage 2 and account 2. This is represented by IDs 4 through 6. For this site, the user has an authentication token plus two query IDs.
id user_id brokerage_id account_id key value
--------------------------------------------------------------------
4 2 2 2 token 999999999999
5 2 2 2 query_id 888888
6 2 2 2 query_id 777777
7 1 2 3 token 444444444444
I am trying to construct a query so that my result will be modeled as such:
[(user_id, brokerage_id, account_id, token, [query_id_1, query_id_2, ...]), ...]
So for the above example, it would look like this
[(2, 2, 2, 999999999999, [888888, 777777]), (1, 2, 3, 444444444444, [])]
I've got the following queries which select the token and the query_ids
tokens = db.session.query(
Key.user_id, Key.brokerage_id, Key.account_id, Key.value
).filter(Key.key=='token').all()
query_ids = db.session.query(
Key.user_id, Key.brokerage_id, Key.account_id, Key.value
).filter(Key.key=='query_id').all()
I've tried using subquery in various ways but cannot quite get the output to resemble what I need. How can I construct a query to return results in a way that align to my list of tuples, above?
Result
Adding the final working query here thanks to #rfkortekaas
from sqlalchemy.orm import aliased
from sqlalchemy import func, and_
from project.models import Key
from project.extensions import db
key_token = aliased(Key)
q = db.session.query(
key_token.user_id,
key_token.brokerage_id,
key_token.account_id,
key_token.value.label('token'),
func.array_agg(Key.value).label('query_ids')
).join(
Key,
and_(
key_token.user_id == Key.user_id,
key_token.brokerage_id == Key.brokerage_id,
key_token.account_id == Key.account_id,
Key.key == 'query_id'
)
).filter(
key_token.key == 'token'
).group_by(
key_token.user_id,
key_token.brokerage_id,
key_token.account_id,
key_token.value
)
results = q.all()
You can use the array_agg function from PostgreSQL to create an array of the results:
from sqlalchemy.orm import aliased
key_token = aliased(Key)
stmt = select(key_token.user_id,
key_token.brokerage_id,
key_token.account_id,
key_token.value.label('token'),
func.array_agg(Key.value).label('query_ids')
).join(Key,
and_(key_token.user_id == Key.user_id,
key_token.brokerage_id == Key.brokerage_id,
key_token.account_id == Key.account_id,
Key.key == 'query_id'))\
.where(key_token.key == 'token')\
.group_by(key_token.user_id,
key_token.brokerage_id,
key_token.account_id,
key_token.value)
keys = session.execute(stmt).all()
for row in keys:
print(row)
Results in:
user_id
brokerage_id
account_id
token
query_ids
1
2
3
'44'
['4']
2
2
1
'33"
['6']
2
2
2
'99"
['8', '7]
For the following dataset:
user_id
brokerage_id
account_id
key
value
2
2
2
token
'99'
2
2
1
token
'33'
2
2
1
query_id
'6'
2
2
2
query_id
'8'
2
2
2
query_id
'7'
1
2
3
token
'44'
1
2
3
query_id
'4'

select case when in MYSQL

I have 2 tables
First tabel name is "consumer"
id_consumer
name
1
Roy
2
Dori
3
Rico
Second tabel name is "consumer_address"
id_consumer
address
status
1
Street Avenue
1
1
Park Hill
0
2
Highwalk Street
1
2
Albion Place
0
Condition
name from tabel "consumer"
address from "consumer_address" , but i want to get only 1 address when consumer_address.status = 1
When Consumer not have data in tabel "consumer_address", field is NULL
The Final Tabel Like this
id_consumer
name
address
status
1
Roy
Street Avenue
1
2
Dori
Highwalk Street
1
3
Rico
NULL
NULL
i have query, but its not work
this is my query
SELECT
id_consumer,
name,
CASE WHEN (`consumer_address`.`status` = 1) THEN `consumer_address`.`address` ELSE NULL END as "Address",
CASE WHEN (`consumer_address`.`status` = 1) THEN `consumer_address`.`status` ELSE NULL END as "Status"
FROM consumer
JOIN consumer_address ON consumer_address.id_consumer = consumer.id_consumer
Thanks
Very simple solution:
SELECT
`id_consumer`,
`name`,
`consumer_address`.`address`,
`consumer_address`.`status`
FROM consumer
LEFT JOIN consumer_address ON
`consumer_address`.`id_consumer` = `consumer`.`id_consumer` AND
`consumer_address`.`status` = 1
Instead of using CASE WHEN just include the status in the JOIN.
Additionally, to keep consumer 3, you need a LEFT JOIN.
SELECT
id_consumer,
name,
`consumer_address`.`address`,
`consumer_address`.`status`
FROM
consumer
LEFT JOIN
consumer_address
ON consumer_address.id_consumer = consumer.id_consumer
AND consumer_address.status = 1

Case statements for multiple fields when only certain cases exist for each field

We have an inventory feature where we generate Bills. There is an Edit Bill API call. We have implemented it as PATCH call.
A Bill with id = 1 has 2 LineItems :
| Stock Id | Qty | Rate |
| 10 | 2 | 10 |
| 11 | 3 | 20 |
Now lets say I want to change the quantity for stock Id : 10 to 5 and I want to change the rate for stock Id : 11 to 40
We have represented it as PATCH Call :
bill : {
id : 1
lineItems : [
{
stockId : 10,
qty : 5,
},
{
stockId : 11,
rate : 40
}
]
}
In the backend we run following query :
UPDATE `billlineitem`
SET `rate` = ( CASE
WHEN stockid = 11 THEN '40'
ELSE rate
END ),
`qty` = ( CASE
WHEN stockid = 10 THEN 5
ELSE qty
END ),
`updated_billitemquantity_at` = '2019-09-06 05:16:06.219'
WHERE `bill_id` = '1'
AND `stockid` IN ( 10, 11 )
Is it ok, in the above case when there is no change for an attribute then the else clause will take the value from the database for that attribute. The above update statement is run in a transaction.
Is this a correct approach? Will this do an update for every attribute for every stock Id. Is there a better approach?
We are using MySQL DB.
What you've written should work, but it will get very complex if you have to update different columns for many different stock IDs. It would probably be simpler, and maybe better performance, to do a separate query for each ID.
BEGIN TRANSACTION;
UPDATE billlineitem
SET rate = '40', `updated_billitemquantity_at` = '2019-09-06 05:16:06.219'
WHERE stockid = 10;
UPDATE billlineitem
SET qty = 5, `updated_billitemquantity_at` = '2019-09-06 05:16:06.219'
WHERE stockid = 11;
COMMIT;

MySQL; Import .SQL and replace single column

Let's say I have the following table in my MySQL database:
id item value
1 Plump A
2 Apple B
3 Banana F
4 Peach K
5 Orange B
6 Cherry U
And I have this table on my computer:
id value
1 B
2 F
3 L
4 A
5 B
6 A
I want to import the table from computer and replace the values from value with the values from value where id = id without changing the values in item.
Means, I need this on my MySQL database at the end:
id item value
1 Plump B
2 Apple F
3 Banana L
4 Peach A
5 Orange B
6 Cherry A
How can I do that?
I ended up with doing the following in Apple Numbers:
Then copy and paste in something like Coda. Search replace tab characters.
Result is:
UPDATE my_table SET value = "B" WHERE id = 1;
UPDATE my_table SET value = "F" WHERE id = 2;
UPDATE my_table SET value = "L" WHERE id = 3;
UPDATE my_table SET value = "A" WHERE id = 4;
UPDATE my_table SET value = "B" WHERE id = 5;
UPDATE my_table SET value = "A" WHERE id = 6;
Now I just have to execute these SQL codes in my database. Done!