show two different values in the same column-SSRS - sql

I need to create a report(SSRS) ,but I can't figure out how i can get one specific value.
Please consider the following scenario: I Have a Hierarchy Country ->City->Person ,& i need to get the value of the wealth in one column for a specific person ,a specific city & a specific country.
the wealth of a counry is not the SUM of the wealth of the persons living in the country .
My report should look like :
USA : 20M$
NY: 3M$
Person1: 0,1M$
Person2: 0,2M$
Boston: 2M$
Person 3: 0,5M$
................
My query is :
;WITH wealth_TEMP AS
(
SELECT
fo.wealthId,
SUM(fo.wealth) AS wealth
FROM
(
SELECT
wealthId,
CASE
WHEN (Some Criteria)
THEN 1
ELSE 0
END AS wealth
FROM wealthTable f
) fo
GROUP BY wealthId
),
Hierarchy AS
(
SELECT
B.CityId AS CityId,
B.CountryName AS CountryName
FROM HierarchyTable AS B where
b.CountryName IN (#Country)
),
Person_Table AS
(
SELECT
fsu.individualId,
fsu.Cityid,
fo.welth
FROM Individual_Table FSU
LEFT OUTER JOIN wealth_TEMP fo ON fo.wealthId = fsu.individualId
WHERE bu.Cityname IN (#City)
)
Select ......................

Considering that your dataset returns something like it:
Country CountryWealth State StateWealth Person PersonWealth
USA 20M$ NY 3M$ Person 1 0,1M$
USA 20M$ NY 3M$ Person 2 0,2M$
USA 20M$ Boston 2M$ Person 3 0,5M$
Create a table with 5 columns and remove the header line
Insert tow new details line
In the first line and first column configure to the Country and Hide Duplicates to true
In the first line and second column configure to the CountryWealth and Hide Duplicates to true
In the second line and second column configure to the State and Hide Duplicates to true
In the second line and third column configure to the StateWealth and Hide Duplicates to true
In the third line and third to the end configure the others values
Order the table to Country, State, person
May, you need to add more columns and merge to get your desired lyout

Related

How to get the values corresponding to another table?

I'm new to SQL and am a bit confused on how I would write a query in order to get the count of state in a different table.
Ie i have this table [student]
id
school_code
0
0123
1
2345
2
2345
And this other table [school]
school_code
name
State
0123
xxyy
New Jersey
2345
xyxy
Washington
3456
yxyx
Colarado
I want to find out how I would get this table which tells me the entries for state by checking each student and making a count of how often that state occurs, ordered by most occurrences in student table.
State
No. times occured (iterating through student)
Washington
2
New Jersey
1
SELECT school.state, count(school.state)
FROM student, school
WHERE student.school_code = school.school_code
GROUP BY school.state
ORDER BY count(school.state)`
I'm not sure whether this would be iterating through each student and counting them?
Or just natural-joinging student and school and then counting all the states
When I run this on data supplied, the numbers of times occurred is a really low number which doesn't seem right?
We can simply JOIN the two tables and COUNT the school code in the students table, with GROUP BY state:
SELECT
sc.state, COUNT(st.school_code)
FROM
school sc
JOIN student st
ON sc.school_code = st.school_code
GROUP BY sc.state;
We can try out here: db<>fiddle

How to create an 'All option' on Access Form dependent on another parameter?

I have a table that looks as follows:
Grade Name
______ ________
1 John
2 Jerry
3 Jack
4 Ben
5 Bill
I have a form with two combo boxes named Combo1 and Combo2. Combo1 has three values- 1,2,3. Combo2 has three values - John, Jerry, All
And I set up the following query:
Select *
From Persons
WHERE
Persons.ID > Forms![Form1]![Combo1]
AND (Persons.Name = Forms![Form1]![Combo2]) OR Forms![Form1]![Combo2]= 'All');
I want the user to be able to select either one or all the Names based on the criteria for Grades but it is not giving me the desired result.
Try this minor modification:
Select
*
From
Persons
WHERE
Persons.ID > Forms![Form1]![Combo1]
AND
(Persons.Name = Forms![Form1]![Combo2] OR Forms![Form1]![Combo2]= 'All');

Populating column for Oracle Text search from 2 tables

I am investigating the benefits of Oracle Text search, and currently am looking at collecting search text data from multiple (related) tables and storing the data in the smaller table in a 1-to-many relationship.
Consider these 2 simple tables, house and inhabitants, and there are NEVER any uninhabited houses:
HOUSE
ID Address Search_Text
1 44 Some Road
2 31 Letsby Avenue
3 18 Moon Crescent
INHABITANT
ID House Name Nickname
1 1 Jane Doe Janey
2 1 John Doe JD
3 2 Jo Smythe Smithy
4 2 Percy Plum PC
5 3 Apollo Lander Moony
I want to to write SQL that updates the HOUSE.Search_Text column with text from INHABITANT. Now because this is a 1-to-many, the SQL needs to collate the data in INHABITANT for each matching row in house, and then combine the data (comma separated) and update the Search_Text field.
Once done, the Oracle Text search index on HOUSE.Search_Text will return me HOUSEs that match the search criteria, and I can look up INHABITANTs accordingly.
Of course, this is a very simplified example, I want to pick up data from many columns and Full Text Search across fields in both tables.
With the help of a colleague we've got:
select id, ADDRESS||'; '||Names||'; '||Nicknames as Search_Text
from house left join(
SELECT distinct house_id,
LISTAGG(NAME, ', ') WITHIN GROUP (ORDER BY NAME) OVER (PARTITION BY house_id) as Names,
LISTAGG(NICKNAME, ', ') WITHIN GROUP (ORDER BY NICKNAME) OVER (PARTITION BY house_id) as Nicknames
FROM INHABITANT)
i on house.id = i.house_id;
which returns:
1 44 Some Road; Jane Doe, John Doe; JD, Janey
2 31 Letsby Avenue; Jo Smythe, Percy Plum; PC, Smithy
3 18 Moon Crescent; Apollo Lander; Moony
Some questions:
Is this an efficient query to return this data? I'm slightly
concerned about the distinct.
Is this the right way to use Oracle Text search across multiple text fields?
How to update House.Search_Text with the results above? I think I need a correlated subquery, but can't quite work it out.
Would it be more efficient to create a new table containing House_ID and Search_Text only, rather than update House?

How can I group flight legs together into routes for counting?

I have a person's flight history and want to find their most frequent route. All flights are stored as a single row in a table, even return trips where a->b will be in one row and b->a will be in another.
I need to identify where two legs equate to a route; for example:
This person has flown 16 times in total
New York to Paris 2 times (Flight key: JFKCDG)
Paris to New York 2 times (Flight Key: CDGJFK)
New York to London 3 times (Flight Key: JFKLHR)
Currently I don't know a way to group the first two above as a 'Route' and therefore any query I write considers JFKLHR to be the most frequent route (6 times between NY and London) even though I can see from the data that this person has flown between NY and Paris a total of 10 times
Sample Table:
User ID¦Flight Key
-------------------
1 ¦JFKCDG
1 ¦JFKCDG
1 ¦CDGJFK
1 ¦CDGJFK
1 ¦JFKLHR
1 ¦JFKLHR
1 ¦JFKLHR
Expected Output
User ID¦Flight Key¦Count
------------------------
1 ¦JFKCDGJFK ¦4
Building on the clever idea in the answer by #fancyPants. You can use string functions to compare each leg of a route and patch together a full return trip.
I believe this query should work. The first part of the common table expression turns those flights that are round trips into three parts (src-dst-src) and the second part returns those that are one way (as src-dst).
with flights_cte as (
select
USERID,
case when left(flightkey,3) > right(flightkey,3)
then concat(flightkey, left(flightkey,3))
else concat(right(flightkey,3), flightkey)
end as flightkey,
count(*) count
from flights f
where exists (
select 1 from flights where right(f.flightkey,3) = left(flightKey,3)
)
group by
userid,
case
when left(flightkey,3) > right(flightkey,3)
then concat(flightkey, left(flightkey,3))
else concat(right(flightkey,3), flightkey)
end
union all
select userid, FlightKey, count(*)
from flights f
where not exists (
select 1 from flights where right(f.flightkey,3) = left(flightKey,3)
)
group by UserID, FlightKey
)
select flights_cte.userid, flights_cte.flightkey, flights_cte.count
from flights_cte
join (select userid, max(count) _max_count from flights_cte group by userid) _max
on flights_cte.UserID=_max.UserID and flights_cte.count = _max_count
A sample SQL Fiddle gives this output:
| USERID | FLIGHTKEY | COUNT |
|--------|-----------|-------|
| 1 | JFKCDGJFK | 4 |
Assuming routes are not a single row, otherwise you wouldn't be asking.. (although I would guess that the whole route is in some other table, maybe reservation-related)
Guessing the first step is to group this data by person and flights that compose a 'route'. I have an article called T-SQL: Identify bad dates in a time series where the time series can be modified to detect gaps between legs of over a day (guess) to differentiate routes. Second step would be to convert legs into route, i.e. JFK-CDG and CDG-JFK to single value JFK-CDG-JFK.
Then it would be a single query, counting the above single value route, and ORDER BY that count.
Good luck.

SQL Server - copy data across tables , but copy the data only when it match with a specific column name

For example I got this 2 table
dbo.fc_states
StateId Name
6316 Alberta
6317 British Columbia
and dbo.fc_Query
Name StatesName StateId
Abbotsford Quebec NULL
Abee Alberta NULL
100 Mile House British Columbia NULL
Ok pretty straightforward , how do I copy the stateId over from fc_states to fc_Query, but match it with the StatesName, let say the result would be
Name StatesName StateId
Abee Alberta 6316
100 Mile House British Columbia 6317
Thanks, and both stateName column type is text
How about:
update fc_Query set StateId =
(select StateId from fc_states where fc_states.Name = fc_Query.StatesName)
That should give you the result you're looking for.
This is a different way than what Eddie did, I like MERGE for updates if they're not dead simple (like I wouldn't consider yours dead simple). So if you're bored/curious also try
WITH stateIds as
(SELECT name, MAX(stateID) as stID
FROM fc_states
GROUP BY name)
MERGE fc_Query
on stateids.name = fc_query.statesname
WHEN MATCHED THEN UPDATE
SET fc_query.stateid = convert(int, stid)
;
The first part, from "WITH" to the GROUP BY NAME), is a CTE, that creates a table-like thing - a name 'stateIds' that is good as a table for the immediately following part of the query - where there's guaranteed to be only one row per state name. Then the MERGE looks for anything in the fc_query with a matching name. And if there's a match, it sets it as you want. YOu can make a small edit if you don't want to overwrite existing stateids in fc_query:
WITH stateIds as
(SELECT name, MAX(stateID) as stID
FROM fc_states
GROUP BY name)
MERGE fc_Query
ON stateids.name = fc_query.statesname
AND fc_query.statid IS NOT NULL
WHEN MATCHED THEN UPDATE
SET fc_query.stateid = convert(int, stid)
;
And you can have it do something different to rows that don't match. So I think MERGE is good for a lot of applications. You need a semicolon at the end of MERGE statements, and you have to guarantee that there will only be one match or zero matches in the source (that is "stateids", my CTE) for each row in the target; if there's more than one match some horrible thing happens, Satan wins or the US economy falters, I'm not sure what, just never let it happen.