2016-09-20 1 views
1

Débutant SQL ici. J'ai recherché comment ajouter une colonne calculée à une vue avec des données d'une autre table mais les n'ont pas pu obtenir le résultat désiré.SQL Server 2012 Ajout d'une colonne calculée à une vue d'une autre table avec différents types de données

Tenir compte ce point de vue:

CREATE VIEW [Portfolio].[MTDPNL] 
AS 
SELECT IssuerLS, Issuer, Ticker, SUM (GLPeriod) As [PNL], ReportDate 
FROM Portfolio.DailyPortfolioIssuerLS 
WHERE ReportDate 
BETWEEN 
(SELECT CONVERT(CHAR(10),DATEADD(dd,-(DAY(GetDate())-1),GetDate()), 120)) 
AND 
(SELECT CONVERT(CHAR(10),(getdate()),120)) 
GROUP BY Issuer, Ticker, IssuerLS, ReportDate 

considèrent maintenant cette instruction SELECT qui retourne une valeur entière unique:

SELECT Nav AS [NavBOM] 
FROM Portfolio.DailyStats ds 
WHERE Date = (SELECT CONVERT(CHAR(10),DATEADD(dd,-(DAY(GetDate())-1),GetDate()), 120)) 

Je veux ajouter une colonne à mon avis est PNL/NavBom. En d'autres termes, pour chaque rangée, je veux ajouter une colonne qui prend le numéro de la colonne PNL comme numérateur et le divise par le numéro NavBOM (donc le dénominateur est le même pour chaque ligne)

J'ai testé avec le code suivant:

SELECT IssuerLS, Issuer, Ticker, SUM (GLPeriod) As [PNL], ReportDate, 
    CAST(SUM (GLPeriod)/(SELECT Nav AS NavBOM 
    FROM Portfolio.DailyStats ds 
    WHERE Date = (SELECT CONVERT(CHAR(10),DATEADD(dd,-(DAY(GetDate())-1),GetDate()), 120))) 
    AS Decimal (7,4)) AS[%ofNAV] 

FROM Portfolio.DailyPortfolioIssuerLS 

WHERE ReportDate BETWEEN 
    (SELECT CONVERT(CHAR(10),DATEADD(dd,-(DAY(GetDate())-1),GetDate()),120)) 
    AND 
    (SELECT CONVERT(CHAR(10),(getdate()),120)) 
GROUP BY Issuer, Ticker, IssuerLS, ReportDate 

Je ne sais pas où le problème est que je reçois une valeur de 0,0000 dans la [% ofNAV] colonne pour chaque ligne. Les deux NavBOM et PNL sont des types de données entiers. Et comme le NavBOM va être un nombre beaucoup plus grand par rapport à PNL, j'ai besoin de le convertir en décimal.

De plus, la vue d'origine que j'ai créée prend près de 4 secondes à s'exécuter. Probablement parce que j'ai des requêtes dans ma clause WHERE. Toute suggestion pour améliorer cela sera grandement appréciée.

Merci!

+1

allant de bas en haut ... vous pouvez supprimer SELECT de la clause where mais il ne va pas être le tueur de performance. Je suppose que ReportDate n'est pas de type Date ou DateTime? Aussi quel est le lien entre vos deux tables. 'DailyStats' et 'DailyPortfolioIssuerLS'? – scsimon

+0

ReportDate est de type Date (aaaa-mm-jj). 'DailyStats' et 'DailyPortfolioLS' n'ont pas vraiment de connexion, sauf qu'ils ont tous deux un numéro de performance pour le portefeuille, mais 'DailyPortfolioLS' a cette information à un niveau plus granulaire. – MilesToGoBeforeISleep

Répondre

1

Voici une méthode utilisant CTE pour obtenir votre NavBOM, puis l'utiliser dans la création de votre vue.

CREATE VIEW [Portfolio].[MTDPNL] 
AS 
WITH cteNav as(
SELECT Nav AS [NavBOM] 
FROM Portfolio.DailyStats ds 
WHERE Portfolio.Date = DATEADD(dd,-(DAY(GetDate())-1),GetDate())) 

SELECT 
    IssuerLS, 
    Issuer, 
    Ticker, 
    SUM (GLPeriod) As [PNL], 
    SUM(CONVERT(DECIMAL(15,2),GLPeriod))/CONVERT(DECIMAL(15,2),cteNav.[NavBOM]) as [%ofNAV] 
    ReportDate 
FROM Portfolio.DailyPortfolioIssuerLS 
JOIN cteNav on 1=1 
WHERE ReportDate BETWEEN CONVERT(DATE,DATEADD(dd,-(DAY(GetDate())-1),GetDate())) AND getdate() --interesting way to get the first day of the month BTW 
GROUP BY 
    Issuer, Ticker, IssuerLS, ReportDate, cteNav.[NavBOM] 
+0

J'ai reçu cette erreur: La colonne 'cteNav.NavBOM' n'est pas valide dans la liste de sélection car elle n'est contenue ni dans une fonction d'agrégat ni dans la clause GROUP BY. J'ai essayé d'ajouter la colonne à la clause GROUP BY après laquelle le code a exécuté mais n'a renvoyé aucune donnée. – MilesToGoBeforeISleep

+0

@MilesToGoBeforeISleep désolé à ce sujet. édité pour ajouter au groupe par – scsimon

+0

Toujours obtenir 0 dans la colonne [& ofNAV]. Je pense que le problème est avec le type de données. Nous divisons un nombre de 3500 par 35 000 000 pour par exemple. Je suspecte la conversion du type de données à quelque chose comme décimal (7,4) va résoudre le problème – MilesToGoBeforeISleep

0

Merci scsimon, le code fonctionne avec un peu tweak:

WITH cteNav as(
SELECT Nav AS [NavBOM] 
FROM Portfolio.DailyStats ds 
WHERE ds.Date = CONVERT(DATE,DATEADD(dd,-(DAY(GetDate())-1),GetDate()))) 


SELECT IssuerLS, Issuer, Ticker, SUM (GLPeriod) As [PNL], 
CAST(SUM(GLPeriod)As Decimal (12,2))/CAST(cteNav.[NavBOM] As Decimal (12,2)) as [%ofNAV], ReportDate 
FROM Portfolio.DailyPortfolioIssuerLS ls 
JOIN cteNav on 1=1 
WHERE ReportDate 
BETWEEN 
CONVERT(DATE,DATEADD(dd,-(DAY(GetDate())-1),GetDate())) 
AND 
CONVERT(CHAR(10),(getdate()),120) 
GROUP BY Issuer, Ticker, IssuerLS, ReportDate, cteNav.[NavBOM] 
GO