Comparing date with the Result Set in Oracle - sql

Below is my query which is going to Generate two rows for me after execution of the query.
SELECT *FROM ELP_COUNTRY,ELP_COUNTRY_Tax where
ELP_COUNTRY.COUNTRY_ID=Elp_Country_Tax.Country_Id
and ELP_COUNTRY.DESCRIPTION='Brasil' and GETENGLISHDESCFROMLISTITEM(ELP_COUNTRY_TAX.TAX_TYPE_ID)='Premiums'
and ELP_COUNTRY_TAX.DEALER_ID is null
This query is returning two rows and again from that rows there is a date named effective date. so again from those rows I want to get the Highest date.
Can anyone help me on this. I am new to Oracle

You could self-join the table with the effective date and evaluate against that by adding something like this: (note the joins may not be correct since I'm just guessing what table the effective date is in and how the tables are related)
and elp_country.effective_date = (select max(e2.effective_date) from elp_country e2 where e2.country_id = elp_country.country_id and elp_country.description = 'Brasil')
Or if it's just a grouping thing you're trying to do then your select would be something like this:
SELECT max(effective_date), column2, column3
FROM ELP_COUNTRY,
ELP_COUNTRY_Tax
where ELP_COUNTRY.COUNTRY_ID=Elp_Country_Tax.Country_Id
and ELP_COUNTRY.DESCRIPTION='Brasil' and
GETENGLISHDESCFROMLISTITEM(ELP_COUNTRY_TAX.TAX_TYPE_ID)='Premiums'
and ELP_COUNTRY_TAX.DEALER_ID is null
group by column2, column3;

You could use the rank function, and wrap that with a "select *" and a where clause predicate filtering the rank of 1, like so:
SELECT * FROM (
SELECT
c.*,
ct.*,
rank() over (order by ct.effective_date) as eff_date_rnk
FROM
ELP_COUNTRY c,
ELP_COUNTRY_Tax ct
WHERE
ELP_COUNTRY.COUNTRY_ID = Elp_Country_Tax.Country_Id
and ELP_COUNTRY.DESCRIPTION='Brasil'
and GETENGLISHDESCFROMLISTITEM(ELP_COUNTRY_TAX.TAX_TYPE_ID)='Premiums'
and ELP_COUNTRY_TAX.DEALER_ID is null
) t
WHERE t.eff_date_rnk = 1;

Related

How to I return a case record with latest date using SQL

I want a query that returns a record set of the shaded rows from the table above for each unique case_id by the latest data_level_assinged value. I tried something like this:
SELECT case_id, level, date_level_assigned
FROM table
SORT BY case_id, date_level_assigned DESC;
From reading it looks like I need to use an aggregate function like MAX(data_level_assinged) but am not sure how to do this.
You're almost there.
Using MAX is a good approach.
SELECT b.case_id, a.level, b.date_level_assigned FROM tablename a
JOIN
( SELECT MAX(date_level_assigned) as date_level_assigned, case_id
FROM tablename
GROUP BY case_id
) as b
ON a.case_id = b.case_id AND a.date_level_assigned = b.date_level_assigned
You can do it in this way

SQL Server, Returning a summed data set grouped by a single column for a merge query

I have a data set like the following:
BaseID| SecondaryTypeID| Value
------------------------------
1 5 1
1 5 3
1 5 8
What I'd like to get is something like:
BaseID| SecondaryTypeID| Value
------------------------------
1 5 12
Now, I can return that data set with the following:
select BaseID,
SecondaryTypeID,
(select sum(Value) from TableA) as SummedValue
from TableA
group by BaseID, SecondaryTypeID
However, I can't do that as part of a merge query, the inner select breaks the merge with an error that looks like this:
Query processor could not produce a query plan because of the hints
defined in this query. Resubmit the query without specifying any hints
and without using SET FORCEPLAN.
Any thoughts on how to resolve this would be gratefully received!
Why would you use a subquery? Just do:
select BaseID, SecondaryTypeID, sum(Value) as SummedValue
from TableA
group by BaseID, SecondaryTypeID;
If you have multiple rows in the result set and want the overall sum, then use window functions:
select BaseID, SecondaryTypeID,
sum(sum(Value)) over () as SummedValue
from TableA
group by BaseID, SecondaryTypeID;
This is what your query really is saying to do. I doubt it is what you want.

Order by data as per supplied Id in sql

Query:
SELECT *
FROM [MemberBackup].[dbo].[OriginalBackup]
where ration_card_id in
(
1247881,174772,
808454,2326154
)
Right now the data is ordered by the auto id or whatever clause I'm passing in order by.
But I want the data to come in sequential format as per id's I have passed
Expected Output:
All Data for 1247881
All Data for 174772
All Data for 808454
All Data for 2326154
Note:
Number of Id's to be passed will 300 000
One option would be to create a CTE containing the ration_card_id values and the orders which you are imposing, and the join to this table:
WITH cte AS (
SELECT 1247881 AS ration_card_id, 1 AS position
UNION ALL
SELECT 174772, 2
UNION ALL
SELECT 808454, 3
UNION ALL
SELECT 2326154, 4
)
SELECT t1.*
FROM [MemberBackup].[dbo].[OriginalBackup] t1
INNER JOIN cte t2
ON t1.ration_card_id = t2.ration_card_id
ORDER BY t2.position DESC
Edit:
If you have many IDs, then neither the answer above nor the answer given using a CASE expression will suffice. In this case, your best bet would be to load the list of IDs into a table, containing an auto increment ID column. Then, each number would be labelled with a position as its record is being loaded into your database. After this, you can join as I have done above.
If the desired order does not reflect a sequential ordering of some preexisting data, you will have to specify the ordering yourself. One way to do this is with a case statement:
SELECT *
FROM [MemberBackup].[dbo].[OriginalBackup]
where ration_card_id in
(
1247881,174772,
808454,2326154
)
ORDER BY CASE ration_card_id
WHEN 1247881 THEN 0
WHEN 174772 THEN 1
WHEN 808454 THEN 2
WHEN 2326154 THEN 3
END
Stating the obvious but note that this ordering most likely is not represented by any indexes, and will therefore not be indexed.
Insert your ration_card_id's in #temp table with one identity column.
Re-write your sql query as:
SELECT a.*
FROM [MemberBackup].[dbo].[OriginalBackup] a
JOIN #temps b
on a.ration_card_id = b.ration_card_id
order by b.id

SQL: Query new rows of a new date

i have table as shown here in this picture --> http://www.directupload.net/file/d/3710/lj7etq5j_png.htm
I need the correct Query to get only data_id 10.
The query should be like this: Compare the latest date rows (2014-08-08) with the earliest date rows (2014-08-06). If there is a row on 2014-08-08 which is NOT at 2014-08-06, this row should returned.
I already tried it with self-joins and Sub-Selects, but i did't get it work.
Thx for any help!
Maybe something like this is what you're looking for?
select * from Table1
where
data not in (
select data from Table1
where dataOfDate = (select min(dataofdate) from Table1)
)
and dataOfDate = (select max(dataofdate) from Table1)
The first where clause compares the data field of the returned rows to the data field in the set of oldest rows and the second where clause limits the set of rows the the newest.
Note that I'm only comparing rows based on thedatafield, so you might have to change the query if you want to includenextTableIdin the comparison.
Here is a sample SQL Fiddle.
How about something like this:
SELECT d1.* FROM Dates d1 LEFT JOIN Dates d2 ON d1.nextTableId = d2.nextTableId WHERE d1.dataofDate = '2014-08-08' AND d2.dataofDate = '2014-08-06' AND d2.data_id IS NULL;
SELECT `data_id`
FROM `my_table`
WHERE `dataOfDate` = (SELECT MAX(`dataOfDate`) FROM `my_table`)
AND `nextTableId` NOT IN (
SELECT `nextTableId` FROM `my_table` WHERE `dataOfDate` = (SELECT MIN(`dataOfDate`) FROM `my_table`)
)
select all rows with max date
that don't have values amongst rows with min date
edit ops, too late

filtering rows by checking a condition for group in one statement only

I have the following statement:
SELECT
(CONVERT(VARCHAR(10), f1, 120)) AS ff1,
CONVERT(VARCHAR(10), f2, 103) AS ff2,
...,
Bonus,
Malus,
ClientID,
FROM
my_table
WHERE
<my_conditions>
ORDER BY
f1 ASC
This select returns several rows for each ClientID. I have to filter out all the rows with the Clients that don't have any row with non-empty Bonus or Malus.
How can I do it by changing this select by one statement only and without duplicating all this select?
I could store the result in a #temp_table, then group the data and use the result of the grouping to filter the temp table. - BUT I should do it by one statement only.
I could perform this select twice - one time grouping it and then I can filter the rows based on grouping result. BUT I don't want to select it twice.
May be CTE (Common Table Expressions) could be useful here to perform the select one time only and to be able to use the result for grouping and then for selecting the desired result based on the grouping result.
Any more elegant solution for this problem?
Thank you in advance!
Just to clarify what the SQL should do I add an example:
ClientID Bonus Malus
1 1
1
1 1
2
2
3 4
3 5
3 1
So in this case I don't want the ClientID=2 rows to appear (they are not interesting). The result should be:
ClientID Bonus Malus
1 1
1
1 1
3 4
3 5
3 1
SELECT Bonus,
Malus,
ClientID
FROM my_table
WHERE ClientID not in
(
select ClientID
from my_table
group by ClientID
having count(Bonus) = 0 and count(Malus) = 0
)
A CTE will work fine, but in effect its contents will be executed twice because they are being cloned into all the places where the CTE is being used. This can be a net performance win or loss compared to using a temp table. If the query is very expensive it might come out as a loss. If it is cheap or if many rows are being returned the temp table will lose the comparison.
Which solution is better? Look at the execution plans and measure the performance.
The CTE is the easier, more maintainable are less redundant alternative.
You haven't specified what are data types of Bonus and Malus columns. So if they're integer (or can be converted to integer), then the query below should be helpful. It calculates sum of both columns for each ClientID. These sums are the same for each detail line of the same client so we can use them in WHERE condition. Statement SUM() OVER() is called "windowed function" and can't be used in WHERE clause so I had to wrap your select-list with a parent one just because of syntax.
SELECT *
FROM (
SELECT
CONVERT(VARCHAR(10), f1, 120) AS ff1,
CONVERT(VARCHAR(10), f2, 103) AS ff2,
...,
Bonus,
Malus,
ClientID,
SUM(Bonus) OVER (PARTITION BY ClientID) AS ClientBonusTotal,
SUM(Malus) OVER (PARTITION BY ClientID) AS ClientMalusTotal
FROM
my_table
WHERE
<my_conditions>
) a
WHERE ISNULL(a.ClientBonusTotal, 0) <> 0 OR ISNULL(a.ClientMalusTotal, 0) <> 0
ORDER BY f1 ASC