Yorumları: 4
Konuları: 0
Kayıt Tarihi: 19-10-2019
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 21 Başlangıç
slm kardeşim
en garantisi triger kullanman bunun haricinde tüm kodlar problem yaşatacatır.
biliyorsun muhasebeciler her zaman faturalar işlenirken tarih sırasına göre işlerler bu sebeple en kolay yöntem triger oluşturmak bu sunucuyuda yormaz senide delphi kodlama derdinden kurtarır
yok delphi ile komut ile tetikleyeyim istiyorsan bir procedure yazmanı tavsiye ederim,
ama zaten bu işin daha iyisini triger yapar (işlenen son faturadaki ürün fiyatlarını alıp ürün listesine son alış fiyatı olarak işleyebilirsin).
Yorumları: 296
Konuları: 34
Kayıt Tarihi: 28-03-2017
Rep Puanı: 2.072 Programcı
(28-08-2020, Saat: 11:06)adelphiforumz Adlı Kullanıcıdan Alıntı: Merhaba Arkadaşlar
MS SQL üzerinde 2 adet tablom yer alıyor bu tablolardan 1 tanesi Master (Alis) diğeri Detail (AlisDetay) seklinde
Bu tablolar içerisinde gelen faturalar ve içeriğindeki ürünler tutuluyor.
Şimdi geleyim problemin detayına
Amacım gelen faturalar içerisindeki ürünlerin son geliş tarihine göre son fiyatını almaya çalışıyorum
Aynı tarih içerisinde aynı ürün için 1 den fazla fatura gelebilmektedir.
Bu durumda son kayıt edilen ürünün fiyatı geçerli olacaktır.
Bunu sağlayan AlisDetay tablosundaki IdAlisDetay alanıdır.
NOT
Bu işlemi bir alt fonksiyon yazmadan yapmaya çalışıyorum.
IdUrun ve Fiyat şeklinde olanı aşağıdaki scriptte yer aldığı şekilde çözümlendi.
Fakat IdUrun, FaturaTarihi, NetFiyat şeklinde daha pratik bir çözüm yolu varmıdır.
Amacım bu sorguyu bir view yada procedure haline getirip AlisDetay tablosundaki tüm ürünlerin son alış tarihini ve son fiyatlarını bir liste halinde elde etmektir.
Şimdiden zaman ayıran arkadaşlara teşekkürler
ÖRNEK Tablolar, Örnek sorgu ve Veri içerikleri aşağıdaki şekildedir.
select SONFATID.IdUrun, Dty.NetFiyat
from (select TRHLI.IdUrun, max(TUMLISTE.IdAlis) as SONID
from (select AD.IdUrun, max(A.FaturaTarihi) as SONTARIH
from AlisDetay AD
inner join Alis A on A.IdAlis = AD.IdAlis
group by AD.IdUrun
) as TRHLI
inner join (select AD.IdUrun, A.FaturaTarihi, A.IdAlis
from AlisDetay AD
inner join Alis A on A.IdAlis = AD.IdAlis) as TUMLISTE on TUMLISTE.IdUrun = TRHLI.IdUrun and TUMLISTE.FaturaTarihi = TRHLI.SONTARIH
group by TRHLI.IdUrun) as SONFATID
inner join AlisDetay Dty on Dty.IdUrun = SONFATID.IdUrun and Dty.IdAlis = SONFATID.SONID
USE [TEST]
GO
/****** Object: Table [dbo].[Alis] Script Date: 27.08.2020 17:45:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Alis](
[IdAlis] [int] NOT NULL,
[FaturaTarihi] [datetime] NULL,
CONSTRAINT [PK_Alis] PRIMARY KEY CLUSTERED
(
[IdAlis] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[AlisDetay] Script Date: 27.08.2020 17:45:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AlisDetay](
[IdAlisDetay] [int] IDENTITY(1,1) NOT NULL,
[IdAlis] [int] NULL,
[IdUrun] [int] NULL,
[NetFiyat] [decimal](18, 2) NULL,
CONSTRAINT [PK_AlisDetay] PRIMARY KEY CLUSTERED
(
[IdAlisDetay] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Alis] ([IdAlis], [FaturaTarihi]) VALUES (1, CAST(N'2020-08-01T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Alis] ([IdAlis], [FaturaTarihi]) VALUES (2, CAST(N'2020-08-01T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Alis] ([IdAlis], [FaturaTarihi]) VALUES (3, CAST(N'2020-08-01T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Alis] ([IdAlis], [FaturaTarihi]) VALUES (4, CAST(N'2020-08-05T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Alis] ([IdAlis], [FaturaTarihi]) VALUES (5, CAST(N'2020-08-05T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Alis] ([IdAlis], [FaturaTarihi]) VALUES (6, CAST(N'2020-08-06T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Alis] ([IdAlis], [FaturaTarihi]) VALUES (7, CAST(N'2020-08-06T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Alis] ([IdAlis], [FaturaTarihi]) VALUES (8, CAST(N'2020-08-06T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[Alis] ([IdAlis], [FaturaTarihi]) VALUES (9, CAST(N'2020-08-06T00:00:00.000' AS DateTime))
GO
SET IDENTITY_INSERT [dbo].[AlisDetay] ON
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (1, 1, 1, CAST(5.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (2, 1, 2, CAST(5.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (3, 1, 3, CAST(5.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (4, 2, 1, CAST(3.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (5, 2, 2, CAST(3.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (6, 2, 2, CAST(3.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (7, 3, 1, CAST(2.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (8, 3, 2, CAST(2.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (9, 3, 3, CAST(2.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (10, 4, 1, CAST(10.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (11, 4, 2, CAST(5.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (12, 5, 3, CAST(3.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (13, 6, 1, CAST(4.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (14, 6, 2, CAST(4.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (15, 6, 3, CAST(4.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (16, 7, 2, CAST(8.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (17, 8, 1, CAST(2.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (18, 8, 2, CAST(6.50 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (19, 9, 1, CAST(3.50 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (20, 9, 2, CAST(4.50 AS Decimal(18, 2)))
GO
INSERT [dbo].[AlisDetay] ([IdAlisDetay], [IdAlis], [IdUrun], [NetFiyat]) VALUES (21, 9, 3, CAST(5.50 AS Decimal(18, 2)))
GO
SET IDENTITY_INSERT [dbo].[AlisDetay] OFF
GO
Ürünlerin son alış fiyatını almak için aşağıdaki benzeri bir SQL kodu kullanabilirsiniz. Ben kodu test edebilmek için kendi veritabanı yapıma göre yazdım. Siz TABLE ve COULUMN adlarını, sorgu koşullarını kendinize göre düzeltirsiniz.
SELECT
TBL_SON_FIYAT.*
FROM (
SELECT
ROW_NUMBER() OVER (PARTITION BY AlisDetay.STOK_REF ORDER BY AlisDetay.STOK_REF, Alis.TRH DESC) AS SIRA_NO,
AlisDetay.STOK_REF,
Alis.TRH AS FATURA_TRH,
Alis.BELGE_NO AS FATURA_NO,
AlisDetay.FIYAT
FROM
TBL_STOKFISDET AlisDetay
LEFT OUTER JOIN TBL_STOKFIS Alis ON (AlisDetay.STOKFIS_REF = Alis.REF)
) TBL_SON_FIYAT
WHERE
TBL_SON_FIYAT.SIRA_NO = 1
Şimdi bu kodu stok tablomla veya başka herhangi bir tabloyla birleştirmek istersem ortaya:
SELECT
STOK.KOD,
STOK.ADI,
SON_FIYAT.FATURA_TRH,
SON_FIYAT.FATURA_NO,
SON_FIYAT.FIYAT
FROM
TBL_STOK STOK
LEFT OUTER JOIN (
SELECT
TBL_SON_FIYAT.*
FROM (
SELECT
ROW_NUMBER() OVER (PARTITION BY AlisDetay.STOK_REF ORDER BY AlisDetay.STOK_REF, Alis.TRH DESC) AS SIRA_NO,
AlisDetay.STOK_REF,
Alis.TRH AS FATURA_TRH,
Alis.BELGE_NO AS FATURA_NO,
AlisDetay.FIYAT
FROM
TBL_STOKFISDET AlisDetay
LEFT OUTER JOIN TBL_STOKFIS Alis ON (AlisDetay.STOKFIS_REF = Alis.REF)
) TBL_SON_FIYAT
WHERE
TBL_SON_FIYAT.SIRA_NO = 1
) SON_FIYAT ON (STOK.REF = SON_FIYAT.STOK_REF)
şeklinde bir kod çıkacaktır. Takıldığınız yer olursa yardımcı olmaya çalışırım.
Yorumları: 820
Konuları: 135
Kayıt Tarihi: 07-12-2017
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 3.030 Uzman
@ csunguray paylaşım için teşekkürler
benim yazdığım örnek ile @ uparlayan nın verdiği örneklerin karması şeklinde olmuş sizinkide farklı bir bakış açısı sonuç aynı
Bu dünyada kendine sakladığın bilgi ahirette işine yaramaz.
Yorumları: 230
Konuları: 9
Kayıt Tarihi: 07-07-2017
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.713 Programcı
17-09-2020, Saat: 11:08
(Son Düzenleme: 17-09-2020, Saat: 11:20, Düzenleyen: sabanakman.)
Performans olarak incelemek gerekebilir sorguları ama başka bir yöntem de benden olsun. Bu yapı SQL Server özelinde kalabilir yalnız. select ana.*, detay.* from Alis ana
cross apply (select top 1 * from AlisDetay alt where alt.IdAlis=ana.IdAlis order by Tarih desc, SiraNo desc) detay
cross apply içinde kullanılan tablonun where şartında (belki order by ile sıralamada kullanılan alanlarında da) indeks tanımlı ise performans sıkıntısı çıkmaz diye tahmin ediyorum.
Yorumları: 46
Konuları: 0
Kayıt Tarihi: 02-12-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 243 Acemi
17-09-2020, Saat: 11:41
(Son Düzenleme: 17-09-2020, Saat: 11:47, Düzenleyen: hasangoktas.
Sebep: Kod görünürlüğü, ve Kod Düzeltmesi.
)
Merhaba Cross Apply ile sorgu zamanı uzun sürüyor. Alttaki gibi de yapabilirsiniz. Tablo ismi ve Field isimlerini kendinize göre değiştiriniz.
SELECT
(
SELECT TOP 1 FD.BIRIMFIYAT
FROM FISDETAY FD WITH (NOLOCK) INNER JOIN
FISBASLIK FB WITH (NOLOCK) ON FD.FISID = FB.ID WHERE FD.URUNID = U.ID
ORDER BY FB.TARIH DESC
) SONFIYAT,
U.* FROM URUN U WITH (NOLOCK)
Yorumları: 230
Konuları: 9
Kayıt Tarihi: 07-07-2017
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.713 Programcı
Cross apply'in yavaş çalışma sebebi her satır için buradaki sorguyu tekrar tekrar çalıştırmasından kaynaklıdır. Aynı yavaşlık bu mantıkla yazılan bir alan değeri getirmek için çağrılan alt tablo sorgusu için de geçerlidir. Hatta alt tablo boşsa sizin belirttiğiniz yöntemi bire bir karşılayan outer apply olacaktır. Zira detayı olmayan kayıtlar cross aply sorguda gelmeyecektir.
Eğer sorgulanan tek alan ise her iki yöntem arasında performans olarak pek bir fark yoktur ama alt sorgudan başka alanlara da ihtiyaç duyulursa outer (ya da cross) apply tekrar tekrar çalıştırılmaz. Elimde yaklaşık ana tabloda 72000 x alt tabloda 236000 kayıt olan bir sorguda deneme yaptım ve calculated alan değeri üzerinden sıralama yaparak test ettiğimde tek alan çağrısında ikisi de aynı performansı gösterdi (yaklaşık 4 sn) fakat alt tablodan 3 alan çektiğimde outer apply doğal olarak yine 4 sn sürdü ama diğer yöntem yaklaşık 10 sn sürdü.
Yorumları: 17
Konuları: 1
Kayıt Tarihi: 15-09-2020
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 172 Başlangıç
Bir öneri : Eğer faturalardan hareket ederek son alış fiyatını buluyorsanız ve Alışlar tablosunda satıştan iadeleri de tutuyor iseniz sorguda bunu da göz önünde bulundurunuz.
Bilmeyen ve bilmediğini bilen çocuktur, ona öğretin.
Bilen ve bildiğini bilmeyen uykudadır, onu uyandırın.
Bilmeyen ve bilmediğini bilmeyen aptaldır, ondan sakının.
Bilen ve bildiğini bilen öncüdür, onu izleyin.
Yorumları: 277
Konuları: 25
Kayıt Tarihi: 10-08-2019
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.137 Programcı
25-09-2020, Saat: 19:06
(Son Düzenleme: 25-09-2020, Saat: 19:07, Düzenleyen: serdar.)
Merhaba benım onerım su sekılde
SELECT al.IdAlis,
al.FaturaTarihi,
a.IdAlisDetay,
a.IdUrun,
a.NetFiyat
FROM AlisDetay a
JOIN Alis al on Al.IdAlis=a.IdAlis
JOIN (SELECT max(da.IdAlisDetay) AS IdAlisDetay
FROM AlisDetay da
GROUP BY da.IdUrun
) T ON T.IdAlisDetay=a.IdAlisDetay
Yorumları: 101
Konuları: 7
Kayıt Tarihi: 30-06-2019
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 334 Acemi
(25-09-2020, Saat: 19:06)serdar Adlı Kullanıcıdan Alıntı: Merhaba benım onerım su sekılde
SELECT al.IdAlis,
al.FaturaTarihi,
a.IdAlisDetay,
a.IdUrun,
a.NetFiyat
FROM AlisDetay a
JOIN Alis al on Al.IdAlis=a.IdAlis
JOIN (SELECT max(da.IdAlisDetay) AS IdAlisDetay
FROM AlisDetay da
GROUP BY da.IdUrun
) T ON T.IdAlisDetay=a.IdAlisDetay
id'si en büyük olan alış, hareketin son alış olduğu anlamına gelmez. alış hareketenin tarihine hiç bakmadan son alışı bulmak felaket olacaktır. bu sql yanlış sonuç verir.
Yorumları: 277
Konuları: 25
Kayıt Tarihi: 10-08-2019
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.137 Programcı
25-09-2020, Saat: 22:20
(Son Düzenleme: 25-09-2020, Saat: 22:22, Düzenleyen: serdar.)
@ bibilen gecmis tarihe kayit eklenebilir haklisin simdi farkettim. Ama ayni tarihe ayni urunden alis yaparsa hangisinin sonuncu oldugunu nasil belirleycegiz? Sanirim zamanin tekilligi saglanmali. Yani tarih alani datetime ve (tarih,idurun) ikilisine unique index verilirse sorun ortadan kalkar diye dusunuyorum
|