Writing SQL query --- - sqlplus

Can somebody help to rewrite this query. I am not sure whether we can achieve this result by writing query or we have to write a procedure for this.
I need result from this query in two separate columns where lm.listingmanagerid=bd.renterid and lm.listingmanagerid<>bd.renterid in separate column.
Please help me.
I want both columns in select section (where lm.listingmanagerid=bd.renterid and lm.listingmanagerid<>bd.renterid)
By using below query I am getting results where listingmanagerID's are matching with bookingdetails table, can I get unmatched ID's from both tables in different column
select bd.listingid from bookingdetails bd, listingmanager lm where lm.listingmanagerid=bd.renterid
Below the structure for both tables
CREATE TABLE BOOKINGDETAILS (
BOOKINGDETAILSID VARCHAR2(28) NOT NULL,
LISTINGID VARCHAR2(28) NOT NULL,
TRAVELLERPROTECTIONID VARCHAR2(28),
TRAVELLERID VARCHAR2(28) NOT NULL,
TRAVELLERNAME VARCHAR2(50) NOT NULL,
CHECKINDATE DATE NOT NULL,
CHECKOUTDATE DATE NOT NULL,
NOOFGUEST NUMBER NOT NULL,
TERMSANDCON LONG RAW,
BOOKINGSTATUS NUMBER DEFAULT 0 NOT NULL,
BOOKINGDATE DATE NOT NULL,
UPDATEDATE DATE,
UPDATEDBY VARCHAR2(50) NOT NULL,
CURRENCYCODE VARCHAR2(10),
BOOKINGAMOUNT FLOAT,
AOVSERVICEFEE FLOAT,
AMENITYWITHFEE VARCHAR2(3000),
OCA NUMBER NOT NULL,
RENTALTOTALAMOUNT FLOAT,
AMENITIESFEE FLOAT,
RENTERID VARCHAR2(28),
CANCELLATIONAMOUNT FLOAT,
PAYMENTID VARCHAR2(28),
CCNUMBER VARCHAR2(30),
LISTINGMANAGERID VARCHAR2(28),
OWNERVIEWSTATUS NUMBER(2) DEFAULT 0,
OWNERVIEWSTATUSDATE DATE,
BOOKINGSTATUSDATE DATE,
OWNERPAYOUTSTATUS NUMBER(2) DEFAULT 0,
OWNERPAYOUTSTATUSDATE DATE,
DISPUTESTATUS NUMBER(2) DEFAULT 0,
DISPUTESTATUSDATE DATE,
TRAVELLERPAYMENTSTATUS NUMBER(2) DEFAULT 0,
TRAVELLERPAYMENTSTATUSDATE DATE,
REJECTIONREASON NUMBER(10),
REJECTIONREASONDETAIL VARCHAR2(200),
CONSTRAINT SYS_C004345
PRIMARY KEY ( BOOKINGDETAILSID )
);
CREATE TABLE LISTINGMANAGER (
LISTINGMANAGERID VARCHAR2(28) NOT NULL,
FIRSTNAME VARCHAR2(30) NOT NULL,
LASTNAME VARCHAR2(30) NOT NULL,
PRIMARYPHONE VARCHAR2(20) NOT NULL,
ALTERNATEPHONE VARCHAR2(20),
EMAIL VARCHAR2(100) NOT NULL,
USERNAME VARCHAR2(100) NOT NULL,
PASSWORD VARCHAR2(32) NOT NULL,
RECALLGUID VARCHAR2(32),
CUSTOMERSINCE DATE,
LASTUPDATED DATE NOT NULL,
UPDATEDBY VARCHAR2(28) NOT NULL,
OCA NUMBER NOT NULL,
PWCHANGEREQUIRED VARCHAR2(1),
PWEXPIREDATE DATE,
LASTLOGIN DATE,
CALLINGHOURS VARCHAR2(200),
TIMEZONEID VARCHAR2(20),
CREATEDATE DATE,
CREATEIPADDRESS VARCHAR2(16),
AUTORENEWFLAG VARCHAR2(1),
AUTORENEWREMOVEDDATE DATE,
AUTORENEWDATE DATE,
ISSUPPLIER VARCHAR2(1) DEFAULT 'N',
PREFFEREDLANGUAGE VARCHAR2(2),
LOCALEID VARCHAR2(2),
ADDRESS1 VARCHAR2(50),
ADDRESS2 VARCHAR2(50),
CITYID VARCHAR2(28),
COUNTRYID VARCHAR2(28),
STATEPROVINCEID VARCHAR2(28),
POSTALCODE VARCHAR2(10),
REGISTRATIONSOURCE VARCHAR2(1),
PPCTYPEID VARCHAR2(28),
ABOUTME VARCHAR2(2000),
PICTUREFILEPATH VARCHAR2(200),
ISPROFILEPICTUREDISPLAY VARCHAR2(1),
GHOSTUSER VARCHAR2(1) DEFAULT 'N',
PROFILEID VARCHAR2(10),
CONSTRAINT SYS_C005739
PRIMARY KEY ( LISTINGMANAGERID ) ,
CONSTRAINT USERNAME_CONSTRAINT
UNIQUE(USERNAME)
);
Thanks

SELECT bookingdetails.listingid AS owner from bookingdetails INNER JOIN listingmanager ON listingmanager.listingmanagerid = bookingdetails.renterid
May be, you need this.

Related

Performing merge with JOIN statement in SNOWFLAKE

I was trying to understand if I can perform merge along with join to load data into a table.
In my scenario, I used merge statement to load data into my PRODUCTSDETAIL table using data from staging table but I was not able to populate a foreign key column (PRODUCTID) since that is the primary key of DIM_PRODUCT table and is autoincremented.
It shows null on executing the merge statement. Can I do Join inside the merge statement in SNOWFLAKE.
If I can, could someone please help me in accomplishing this. I was also not sure if snowflake could automatically populate the foreign key based on the PRODUCTNAME
Below is the code for creation statement of PRODUCTDETAILS Table
Create table PRODUCTSDETAIL(
ProductsdetailID NUMBER(38,0) NOT NULL autoincrement,
CUSTOMERID NUMBER(38,0),
PRODUCTID NUMBER(38, 0),
PRODUCTunit varchar(255),
PRODUCTname varchar(255),
PRODUCTcode varchar(255),
PRODUCTquantity varchar(255),
PURCHASEdate TIMESTAMP_NTZ(9),
foreign key (PRODUCTID) references test."manufacturer".dim_product(PRODUCTID))
Below is the merge statement I am using to load and got NULL values for PRODUCTSID
merge into PRODUCTDETAILS as a using (
select
CUSTOMERID,
f.value as Productunit,
Productname[f.index]::Varchar as Productname,
Productcode [f.index]::Varchar as Productcode,
Productquantity [f.index]::Varchar as Productquantity,
PURCHASEDate [f.index]::Timestamp as PURCHASEDate
from staging_json b
LATERAL FLATTEN(Productunit, RECURSIVE=>true)f) as b on a.PURCHASEDate = b.PURCHASEDate
and a.Productcode = b.Productcode and a.CUSTOMERID = b.CUSTOMERID
and a.Productquantity = b.Productquantity
when not matched then insert (CUSTOMERID, PRODUCTID, Productunit, Productname, Productcode,Productquantity, PURCHASEDate)
values (CUSTOMERID, PRODUCTID, Productunit, Productname, Productcode,Productquantity, PURCHASEDate)
When I did insert using Join after the execution of above merge statement the PRODUCTID got added below the records will NULL values populated for other columns as below screenshot
Below is insert statement I ran after the above merge statment and values got added below
insert into PRODUCTSDETAIL(PRODUCTID)
select a.PRODUCTID
from DIM_PRODUCT a
inner join PRODUCTSETAIL b on a.PRODUCTNAME = b.PRODUCTNAME
where b.PRODUCTID is null;
I tried to do a left join inside the merge statement to fetch PRODUCTID from DIM_PRODUCT but it throws an error UNKNOWN LEFT JOIN
Below is the syntax for that
**
merge into PRODUCTDETAILS as a using (
select
CUSTOMERID,
f.value as Productunit,
Productname[f.index]::Varchar as Productname,
Productcode [f.index]::Varchar as Productcode,
Productquantity [f.index]::Varchar as Productquantity,
PURCHASEDate [f.index]::Timestamp as PURCHASEDate
from staging_json b
LEFT JOIN DIM_PRODUCTS c ON c.PRODUCTNAME = a.PRODUCTNAME,
LATERAL FLATTEN(Productunit, RECURSIVE=>true)f) as b on a.PURCHASEDate = b.PURCHASEDate
and a.Productcode = b.Productcode and a.CUSTOMERID = b.CUSTOMERID
and a.Productquantity = b.Productquantity
when not matched then insert (CUSTOMERID, PRODUCTID, Productunit, Productname, Productcode,Productquantity, PURCHASEDate)
values (CUSTOMERID, PRODUCTID, Productunit, Productname, Productcode,Productquantity, PURCHASEDate)
**

Populate Foreign Key values automatically in SNOWFLAKE

I have two tables as per the below structure in SNOWFLAKE database and I am trying to merge data from the staging table onto the below two tables.
Primary key of DIM_PRODUCTS table below is PRODUCTID
Primary Key of PRODUCTSDETAIL table is PRODUCTSDETAILID and the CUSTOMERID is generated in the stagingtbale using nextval
My understanding is if I create a table with referencing the foreign key, then the values should populate automatically for that column if the corresponding names are found but in my case it shows NULL values.
Below is the syntax I used to create the DIM_PRODUCT table and the PRODUCTSDETAIL table
create or replace TABLE DIM_PRODUCT cluster by (PRODUCTID)(
PRODUCTID NUMBER(38,0) NOT NULL autoincrement,
PRODUCTName VARCHAR(),
primary key (PRODUCTID)
);
Create table PRODUCTSDETAIL(
ProductsdetailID NUMBER(38,0) NOT NULL autoincrement,
CUSTOMERID NUMBER(38,0),
PRODUCTID NUMBER(38, 0),
PRODUCTunit varchar(255),
PRODUCTname varchar(255),
PRODUCTcode varchar(255),
PRODUCTquantity varchar(255),
PURCHASEdate TIMESTAMP_NTZ(9),
foreign key (PRODUCTID) references test."manufacturer".dim_product(PRODUCTID))
Below is the merge statement I used to load data into details table and got NULL values for PRODUCTID
merge into PRODUCTDETAILS as a using (
select
CUSTOMERID,
f.value as Productunit,
Productname[f.index]::Varchar as Productname,
Productcode [f.index]::Varchar as Productcode,
Productquantity [f.index]::Varchar as Productquantity,
PURCHASEDate [f.index]::Timestamp as PURCHASEDate
from staging_json b
LATERAL FLATTEN(Productunit, RECURSIVE=>true)f) as b on a.PURCHASEDate = b.PURCHASEDate
and a.Productcode = b.Productcode and a.CUSTOMERID = b.CUSTOMERID
and a.Productquantity = b.Productquantity
when not matched then insert (CUSTOMERID, PRODUCTID, Productunit, Productname, Productcode,Productquantity, PURCHASEDate)
values (CUSTOMERID, PRODUCTID, Productunit, Productname, Productcode,Productquantity, PURCHASEDate)
I have also created sequences to autoincrement for ProductID and ProductdetailID
I also tried a Join approach to populate the ProductID but it did not work out and the code for that is as below
merge into PRODUCTDETAILS as a using (
select
CUSTOMERID,
f.value as Productunit,
Productname[f.index]::Varchar as Productname,
Productcode [f.index]::Varchar as Productcode,
Productquantity [f.index]::Varchar as Productquantity,
PURCHASEDate [f.index]::Timestamp as PURCHASEDate
from staging_json b
LEFT JOIN DIM_PRODUCTS c ON c.PRODUCTNAME = a.PRODUCTNAME,
LATERAL FLATTEN(Productunit, RECURSIVE=>true)f) as b on a.PURCHASEDate = b.PURCHASEDate
and a.Productcode = b.Productcode and a.CUSTOMERID = b.CUSTOMERID
and a.Productquantity = b.Productquantity
when not matched then insert (CUSTOMERID, PRODUCTID, Productunit, Productname, Productcode,Productquantity, PURCHASEDate)
values (CUSTOMERID, PRODUCTID, Productunit, Productname, Productcode,Productquantity, PURCHASEDate)
I am trying to find the good practice to load the PRODUCTID into the PRODUCTSDETAIL table and make it consistent for querying. Could someone please help me?

Error loading association from controller in cakephp

I can't get this simple query right. I need to join my adresses table to my annonces table.
I supose this should be farly strait forward but I simply can't get it to work.
I firstly made my adresse table object like this
class AdressesTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Annonces', [
'foreignKey' => 'annonceId',
'joinType' => 'INNER',
]);
}
}
Then in my annonces controller I tryed to join the adresses like this
public function view($id = null)
{
if (!$id) {
throw new NotFoundException(__('Annonce invalide!'));
}
$query = $this->Annonces->find('all', ['contain' => ['Adresses']])->where(['id' => $id]);
$annonce = $query->firstOrFail();
$this->set(compact('annonce'));
}
But then I got this error :
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Adresses.annonce_id' in 'where clause'
Witch I don't understand why I got it since I have defined my foreign key in the AdressesTable class.
The query I would like to have at the end would look like this
SELECT *
FROM annonces
INNER JOIN adresses ON adresses.annonceId = annonces.id
WHERE annonces.id = #param
*PS. I know it wont be select * but rather select [all my column]*
EDIT : My table schema are as following
CREATE TABLE annonces(
id INT NOT NULL AUTO_INCREMENT, #PK
startDate DATE NOT NULL,
endDate DATE NOT NULL,
title VARCHAR(128) NOT NULL,
descript TEXT NOT NULL,
infoSupplementaire TEXT NULL,
premium BIT NOT NULL,
clientId INT NOT NULL, #FK
categorieId INT NOT NULL, #FK
CONSTRAINT pk_annonces_id PRIMARY KEY (id),
CONSTRAINT fk_annonces_clientId FOREIGN KEY (clientId) REFERENCES clients(id),
CONSTRAINT fk_annonces_categorieId FOREIGN KEY (categorieId) REFERENCES categories(id)
);
CREATE TABLE adresses(
id INT NOT NULL AUTO_INCREMENT, #PK
latitude DECIMAL(11,7),
longitude DECIMAL(11,7),
adresse VARCHAR(512),
annonceId INT NOT NULL, #FK
CONSTRAINT pk_adresses_id PRIMARY KEY (id),
CONSTRAINT fk_adresses_annonceId FOREIGN KEY (annonceId) REFERENCES annonces(id)
)
I solved my problem by renaming my column folowing cakephp convention and using any of the code from this answer
You can try
$query = $this->Annonces->find('all', ['contain' => ['Adresses']])->where(['Annonces.id' => $id]);
$annonce = $query->firstOrFail();
OR
public function view($id = null)
{
if (!$id) {
throw new NotFoundException(__('Annonce invalide!'));
}
$annonceEntity = $this->Annonces->get($id);
$query = $this->Annonces->find('all', ['contain' => ['Adresses']])->where(['Annonces.id' => $annonceEntity->id]);
$annonce = $query->firstOrFail();
$this->set(compact('annonce'));
}

Elegant linq solution for left joins with unique data

I woud like to inquire if my Linq solution below is a good solution or if there is a better way. I am new to using Linq, and am most familiar with MySQL. So I've been converting one of my past projects from PHP to .NET MVC and am trying to learn Linq. I would like to find out if there is a better solution than the one I came up with.
I have the following table structures:
CREATE TABLE maplocations (
ID int NOT NULL AUTO_INCREMENT,
name varchar(35) NOT NULL,
Lat double NOT NULL,
Lng double NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY name (name)
);
CREATE TABLE reservations (
ID INT NOT NULL AUTO_INCREMENT,
loc_ID INT NOT NULL,
resDate DATE NOT NULL,
user_ID INT NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY one_per (loc_ID, resDate),
FOREIGN KEY (user_ID) REFERENCES Users (ID),
FOREIGN KEY (loc_ID) REFERENCES MapLocations (ID)
);
CREATE TABLE Users (
ID INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
email VARCHAR(50) NOT NULL,
pass VARCHAR(128) NOT NULL,
salt VARCHAR(5) NOT NULL,
PRIMARY KEY (ID),
UNIQUE KEY unique_names (name),
UNIQUE KEY unique_email (email)
);
In MySQL, I use the following query to get the ealiest reservation at each maplocation with a non null date for any locations that don't have a reservation.
SELECT locs.*, if(res.resDate,res.resDate,'0001-01-01') as resDate, res.Name as User
FROM MapLocations locs
LEFT JOIN (
SELECT loc_ID, resDate, Name
FROM Reservations, Users
WHERE resDate >= Date(Now())
AND user_ID = Users.ID
ORDER BY resDate
) res on locs.ID = res.loc_ID
group by locs.ID
ORDER BY locs.Name;
In Linq, with Visual studio automatically creating much of the structure after connecting to the database, I have come up with the following equivalent to that SQL Query
var resList = (from res in Reservations
where res.ResDate >= DateTime.Today
select res);
var locAndRes =
(from loc in Maplocations
join res in resList on loc.ID equals res.Loc_ID into join1
from res2 in join1.DefaultIfEmpty()
join usr in Users on res2.User_ID equals usr.ID into join2
from usr2 in join2.DefaultIfEmpty()
orderby loc.ID,res2.ResDate
select new {
ID = (int)loc.ID,
Name = (string)loc.Name,
Lat = (double)loc.Lat,
Lng = (double)loc.Lng,
resDate = res2 != null ?(DateTime)res2.ResDate : DateTime.MinValue,
user = usr2 != null ? usr2.Name : null
}).GroupBy(a => a.ID).Select(b => b.FirstOrDefault());
So, I'm wondering is there a better way to perform this query?
Are these equivalent?
Are there any good practices I should be following?
Also, one more question, I'm having trouble getting this from the var to a List. doing something like this doesn't work
List<locAndResModel> locList = locAndRes.AsQueryable().ToList<locAndResModel>();
In the above snippet locAndResModel is just a class which has variables to match the int, string, double double, DateTime, string results of the query. Is there an easy way to get a list without having to do a foreach and passing the results to a constructor override? Or should I just add it to ViewData and return the View?
You'll want to take advantage of the automatic joins performed by the Entity Framework. Give this a try and let me know if it does what you want:
var locAndRes = from maplocation in MapLocations
let earliestReservationDate = maplocation.Reservations.Min(res => res.resDate)
let earliestReservation = (from reservation in mapLocation.Reservations
where reservation.resDate == earliestReservationDate && reservation.resDate >= DateTime.Today
select reservation).FirstOrDefault()
select new locAndResModel( maplocation.ID, maplocation.name, maplocation.Lat, maplocation.Lng, earliestReservation != null ? earliestReservation.resDate : DateTime.MinValue, earliestReservation != null ?earliestReservation.User.name : null)

MVC Entity Framework Model not returning correct data

Run into a strange problem while writing an ASP.NET MVC site. I have a view in my SQL Server database that returns a few date ranges. The view works fine when running the query in SSMS.
When the view data is returned by the Entity Framework Model, It returns the correct number of rows but some of the rows are duplicated.
Here is an example of what I have done:
SQL Server code:
EDITED: (table A)
CREATE TABLE [dbo].[A](
[ID] [int] NOT NULL,
[PhID] [int] NULL,
[FromDate] [datetime] NOT NULL,
[ToDate] [datetime] NULL,
CONSTRAINT [PK_A] PRIMARY KEY CLUSTERED
( [ID] ASC,
[FromDate] ASC
)) ON [PRIMARY]
CREATE TABLE [dbo].[B](
[PhID] [int] NOT NULL,
[FromDate] [datetime] NULL,
[ToDate] [datetime] NULL,
CONSTRAINT [PK_B] PRIMARY KEY CLUSTERED
( [PhID] ASC )) ON [PRIMARY]
go
CREATE VIEW C as
SELECT A.ID,
CASE WHEN A.PhID IS NULL THEN A.FromDate ELSE B.FromDate END AS FromDate,
CASE WHEN A.PhID IS NULL THEN A.ToDate ELSE B.ToDate END AS ToDate
FROM A
LEFT OUTER JOIN B ON A.PhID = B.PhID
go
INSERT INTO B (PhID, FromDate, ToDate) VALUES (100, '20100615', '20100715')
INSERT INTO A (ID, PhID, FromDate, ToDate) VALUES (1, NULL, '20100101', '20100201')
INSERT INTO A (ID, PhID, FromDate, ToDate) VALUES (1, 100, '20100615', '20100715')
INSERT INTO B (PhID, FromDate, ToDate) VALUES (101, '20101201', '20101231')
INSERT INTO A (ID, PhID, FromDate, ToDate) VALUES (2, NULL, '20100801', '20100901')
INSERT INTO A (ID, PhID, FromDate, ToDate) VALUES (2, 101, '20101201', '20101231')
So now, if you select all from C, you get 4 separate date ranges
In the Entity Framework Model (which I call 'Core'), the view 'C' is added.
in MVC Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
CoreEntities db = new CoreEntities();
var clist = from c in db.C
select c;
return View(clist.ToList());
}
}
in MVC View:
#model List<RM.Models.C>
#{
foreach (RM.Models.C c in Model)
{
#String.Format("{0:dd-MMM-yyyy}", c.FromDate)
<span>-</span>
#String.Format("{0:dd-MMM-yyyy}", c.ToDate)
<br />
}
}
When I run all this, it outputs this:
01-Jan-2010 - 01-Feb-2010
01-Jan-2010 - 01-Feb-2010
01-Aug-2010 - 01-Sep-2010
01-Aug-2010 - 01-Sep-2010
When it should do this (this is what the view returns):
01-Jan-2010 - 01-Feb-2010
15-Jun-2010 - 15-Jul-2010
01-Aug-2010 - 01-Sep-2010
01-Dec-2010 - 31-Dec-2010
Also, I've run the SQL profiler over it and according to that, the query being executed is:
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[FromDate] AS [FromDate],
[Extent1].[ToDate] AS [ToDate]
FROM (SELECT
[C].[ID] AS [ID],
[C].[FromDate] AS [FromDate],
[C].[ToDate] AS [ToDate]
FROM [dbo].[C] AS [C]) AS [Extent1]
Which returns the correct data
So it seems that the entity framework is doing something to the data in the meantime.
To me, everything looks fine! Have I missed something?
Cheers,
Ben
EDIT:
sorry, table A should be:
CREATE TABLE [dbo].[A](
[ID] [int] NOT NULL,
[PhID] [int] NULL,
[FromDate] [datetime] NOT NULL,
[ToDate] [datetime] NULL,
CONSTRAINT [PK_A] PRIMARY KEY CLUSTERED
( [ID] ASC,
[FromDate] ASC
)) ON [PRIMARY]
I figured it out myself.
The problem was with the way the view was mapped in the entity model.
When it was added, it made the entity key just the ID. I needed it over the ID and FromDate. So I included the FromDate in the entity key and it works fine.

Resources