منظور من این هست که میخواهیم ببینیم در یک جدول چند تا رکورد داریم.همین.
منظور من این هست که میخواهیم ببینیم در یک جدول چند تا رکورد داریم.همین.
اگه ستونی که ایندکس گذاشتی بی همتا باشه بهتره count(FieldName) رو بنویسیم.
ولی اگه یونیک نباشه، خود sql تصمیم میگیره از کدوم ستون استفاده کنه و مینویسیم count(*)
اول اینکه روی فیلدی که clustered index تعریف میشه حتما باید یونیک باشه.
وقتی count(*) مینویسیم خود optimizer تصمیم می گیره از کدام فیلد استفاده کنه ، باعث میشه scan روی جدول صورت بگیره که سربار زبادی داره.
ولی اگر count(clustered index) بنویسسیم مجبور می کنیم ازستون ایندکس برای شمارش استفاده می کنه، گویا اینجا هم باز scan انجام میشه و تفاوتی با مورد قبلی نداره.
ویا می تونیم از دستور زیر استفاده کنیم select count(*) from table with (index=index name) که من چندین مورد سعی کردم query خودم رو مجبود به استفاده از ایندکس بکنم ولی همیشه جوابگو نبوده و اصلا اجباری رو ایجاد نمی کنه و optimizer هر کاری رو صلاح بدونه انجام می ده.
بهترین حل استفاده از اطلاعات ذخیره شده در Sysindexes است.که دیگه table scan نداره.
سلام،
– Row Count without doing full table Scan
– This will include provide total number of rows in all partition (if table is partitioned)
SELECT
Total_Rows=SUM(st.row_count)
FROM
sys.dm_db_partition_stats st
WHERE
object_name(object_id)= ‘Your_Table_Name_Goes_Here’
AND (index_id < 2)– Only Heap or clustered index
سلام.
دوستان جواب مناسبی ارائه ندادند.شما وقتیی که ایندکس دارید خود ایندکس تعداد رکوردهای جدول رو در جدول sys.sysindexes نگهداری میکنه.کافیه مقدار ستون rowcnt رو از این جدول بخونید.با این روش نیازی نیست که یک بار کل جدول scan بشه و سرعتش بسیار بالاتر از دستور Count هست. البته این دستور زمانی کاربرد داره که شما میخواهید تعداد رکوردهای کل جدول رو بدونید.
نظرتان درباره کد پست شده چیست؟
کدی که شما ارسال کردید برای موقعی هست که از table partition استفاده کردیم.
درحالت عادی موردی که عرض کردم جواب سوال می باشد.
فرض کنید اطلاعاتی داریم که دارای یک رابطه درختی با هم هستند یعنی هر یک از این مجموعه اطلاعات یکی از گره های یک درخت هستند، برای پیاده سازی این موضوع جدولی با ساختار زیر طراحی کرده ایم
ID : int
Name : varchar(50)
ParentId : int
که در این ساختار گره های Root دارای ParentId = 0
و برای بقیه گره های فیلد ParentId برابر فیلد Id پدر خود هستند.
1 - دستوری بنویسید که با گرفتن Id یک گره اطلاعات تمام فرزندان اون گره رو نمایش بده
2 - دستوری بنویسید که با گرفتن Id یک گره اطلاعات تمام پدران اون گره رو نمایش بده
فكر كنم از خاصيت formula با ارجاع بخ خود جدول بتوان حل نمود
احتمالا راه حلی به جز استفاده از سلکتهای تو در تو و کرسر داره! اگه با دو مورد ذکر شده باشه که کار خاصی نداره!
مشتاقم راه حل بهتر رو ببینم.
سلام
خدا قوت
میتونیم یک فاکنشن به صورت زیر ایجاد کنیم تا با ارسال سریال اصلی همه فرزندان آنرا نمایش دهد
CREATE FUNCTION [dbo].[Fn_AllSon] (@IdSi int)
RETURNS @RepTable TABLE(IdSon int)
AS
begin
insert into @RepTable(IdSon) values (@IdSi)
WHILE (exists (SELECT 1 from TableName where [Id] not in (select IdSon from @RepTable)
and ParentId in (select IdSon from @RepTable)))
insert @RepTable
select [Id] from TableName where [Id] not in (select IdSon from @RepTable)
and ParentId in (select IdSon from @RepTable)
Return
END
آخرین ویرایش به وسیله حمیدرضاصادقیان : چهارشنبه 20 بهمن 1389 در 23:41 عصر دلیل: از تگ Code برای نوشتن دستورات استفاده کنید.
سلام.
من مدت طولانی صبر کردم ولی دوستان جواب مناسبی ارسال نکردند.
من جوابها رو قرار میدهم.
ابتدا رکوردهای زیر رو وارد میکنیم.
Create Table #Temp (
ID int NULL,
Name varchar(50) NULL,
ParentId int NULL
)
Insert Into #Temp Values(1,'AB1',0)
Insert Into #Temp Values(2,'AB2',0)
Insert Into #Temp Values(3,'CD1',1)
Insert Into #Temp Values(4,'CD2',1)
Insert Into #Temp Values(5,'CD3',1)
Insert Into #Temp Values(6,'EF1',2)
Insert Into #Temp Values(7,'GH1',3)
Insert Into #Temp Values(8,'GH2',5)
Insert Into #Temp Values(9,'IJ1',6)
Insert Into #Temp Values(10,'KL1',7)
Insert Into #Temp Values(11,'MN',10)
Insert Into #Temp Values(12,'OP',11)
جواب سوال 1 :
Declare @Id int
Set @Id = 1
;With RES as(
Select * From #Temp Where Id = @Id
UNION ALL
Select t.*
From #Temp T INNER JOIN RES R
On T.ParentID = R.ID
)
Select * From RES
جواب سوال 2 :
Declare @Id int
Set @Id = 7
;With RES as(
Select * From #Temp Where Id = @Id
UNION ALL
Select t.*
From #Temp T INNER JOIN RES R
On T.ID = R.ParentId
)
Select * From RES
Telegram : @SQL_Server
سلام
البته اگه اشتباه نکنم این روش محدودیت تعدادی داره. یعنی چون از الگوریتم Recursive استفاده می کنه در بیشترین حالت 32767 رکورد رو برمی گردونه و اگه تعداد رابطه پدر و فرزندی بیشتر از این باشه , مشکل پیش می آد. اگرچه در مورد درخت به ندرت پیش می آد , اما به هر حال یک ریسک هست.
SQL Server 2008 help:
ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.en/s10de_1devconc/html/4acf8a3e-6dcc-420c-9088-9c57b976113e.htm
سلام
با تشکر فراوان ن ن ن واقعا استفاده میکینیم
من معمای آخر و درباره ی ساختار درختی اجراش میکنم خطلای زیر و میده
Server: Msg 156, Level 15, State 1, Line 22
Incorrect syntax near the keyword 'With'.
سلام.
این تاپیک رو بالا آوردم تا دوباره معماهای جدید رو مطرح کنیم.
خوب برای شروع به سوال زیر پاسخ دهید.
دستورات زیر رو اجراکنید.
CREATE TABLE Employee
(
EmployeeID INT,
EmployeeName VARCHAR(30),
Country VARCHAR(20)
);
CREATE TABLE Orders
(
EmployeeId INT,
OrderId INT,
Price Money
);
INSERT INTO Employee
VALUES(1,'Martin','Canada'),
(2,'Jim','USA'),
(3,'Steve','Turkey');
INSERT INTO Orders
VALUES(1,1,10000),
(1,2,20000),
(1,3,54000),
(3,1,18700),
(3,2,9768),
(3,3,7577887);
خوب حالا ما میخواهیم لیست مشتریانی که فروش نداشتند و کشور آنها USA هست رو بدست بیاریم.
ابتدا دستور زیر رو اجرا میکنیم.
SELECT E.EmployeeId,E.EmployeeName,O.EmployeeId,o.OrderId ,o.Price
FROM Employee e
LEFT OUTER JOIN
Orders o
ON o.EmployeeId=E.EmployeeID
AND E.Country='USA'
ولی نتیجه دلخواه رو به مانمیده و جواب اشتباه برمیگردونه در صورتی که ما میتوانیم شرط رو در عبارت ON هم بنویسیم.
حال به شکل زیر دستورو مینویسیم.
SELECT E.EmployeeId,E.EmployeeName,O.EmployeeId,o.OrderId ,o.Price
FROM Employee e
LEFT OUTER JOIN
Orders o
ON o.EmployeeId=E.EmployeeID
Where E.Country='Usa'
الان مشتری شماره 2 را برمیگرداند.
چه تفاوتی بین نوشتن شرط در ON و Where هست؟
چرا با تغییر شرط نتیجه ما تغییر کرد؟
Telegram : @SQL_Server
سلام،
دلیلش اینه که WHERE Clauseروی نتیجهٔ Join اجرا میشه یعنی اول Join رو روی کلید انجام میده بعد نتیجهٔ حاصل رو طبق WHERE Clause محدود میکنه ولی در ON Clause اینطور نیست.
It means ON Clause applies before JOIN but WHERE Clause applies on complete result so it removes all rows which are not in criteria.
PLEASE NOTE : There is no difference between WHERE Clause and ON Clause when used with INNER JOIN.
ممنون توضیح شما درسته ولی کامل توضیح ندادین.
ببینید وقتی که دستورات Parse می شوند در Outer Join ابتدا به صورت یک Inner join عمل کرده و هردو جدول براساس قیدهایی که در On ذکر شده باهم Join می شوند و بعد از آن دوباره عمل Join با جدول فوق صورت میگیرد که سبب می شود رکوردهایی که الان در جدول اصلی نیست رو به صورت null به ما نشون میده و در واقع دوبار عمل join انجام میشه یک بار با استفاده از on یک بار بعد از اینکه جدول از on تشکیل شد. به همین خاطر باید در Outer Join شرط رو در where بنویسید تا نتیجه درست بگیرید ولی در Inner join چون یک بار عملیات تشکیل جدول مجازی صورت گرفته و دیگه join اضافی انجام نمی شود به همین خاطر در همون مرحله اولیه ON نیز بر روی جدول صورت میگیرد. به همین خاطر در Inner join تفاوتی نداره که شرط رو در on بنویسید یا در where.
دلیل کندی Outer join نسبت به Inner join نیز همین امر هست.
Telegram : @SQL_Server
سلام
کاش این تاپیک ادامه پیدا کنه ...
یه نکته ای رو خواستم بگم که به اصل نکته سوال کاری نداره , در مورد آخرین کوئری , شما فرموده بودین مشتریانی که فروش نداشتن , برای همین تو شرط where باید
and o.price is nullرو هم اضافه کنیم
باز هم از ایجاد این تاپیک ممنون
SELECT T.name AS TableName ,
P.rows
FROM sys.partitions AS P
INNER JOIN sys.tables AS T ON T.object_id = P.object_id
WHERE T.name = 'TableName'
تو mysql کافیه یک select * بزنیم.بعدش با یک mysql_num_rows()
کار تمومه.
سلام ممنون از تایپیک جالبتون
در راه حل دوم جدول Employee به همراه تمام سفارشاتشون برمیگرده و سپس با شرط WHERE اون هایی که کشورشون USA هست فیلتر میشن
برای بررسی دستور اول ایتدا برای دستور زیر به همراه خروجیش رو بررسی میکنیم
SELECT E.EmployeeId,E.EmployeeName ,e.country,O.EmployeeId,o.OrderId,o.PriceFROM
Employee eLEFT OUTER JOINOrders oON o.EmployeeId=E.EmployeeID
+------------+--------------+---------+------------+---------+---------+
| EmployeeId | EmployeeName | country | EmployeeId | OrderId | Price |
+------------+--------------+---------+------------+---------+---------+
| 1 | Martin | Canada | 1 | 1 | 10000 |
| 1 | Martin | Canada | 1 | 2 | 20000 |
| 1 | Martin | Canada | 1 | 3 | 54000 |
| 2 | Jim | USA | NULL | NULL | NULL |
| 3 | Steve | Turkey | 3 | 1 | 18700 |
| 3 | Steve | Turkey | 3 | 2 | 9768 |
| 3 | Steve | Turkey | 3 | 3 | 7577887 |
+------------+--------------+---------+------------+---------+---------+
و دستور زیر
SELECT E.EmployeeId,E.EmployeeName,O.EmployeeId,o.OrderId ,o.PriceFROM Employee eLEFT OUTER JOINOrders oONo.EmployeeId=E.EmployeeIDAND E.Country='Canada'
+------------+--------------+------------+---------+-------+
| EmployeeId | EmployeeName | EmployeeId | OrderId | Price |
+------------+--------------+------------+---------+-------+
| 1 | Martin | 1 | 1 | 10000 |
| 1 | Martin | 1 | 2 | 20000 |
| 1 | Martin | 1 | 3 | 54000 |
| 2 | Jim | NULL | NULL | NULL |
| 3 | Steve | NULL | NULL | NULL |
+------------+--------------+------------+---------+-------+
در واقع میبینیم شرطon روی نوع تلفیق اثر گذار هست و چون تلیق خارجی هست ستون های جدول Employee در هر صورت بازگردانده میشن
سلام
خطا میده
چون در این دستور وقتی پیوندی باشه امکان حذف نیست
سلام میخواستم عدد صفر جز کوچکترین عدد حساب نشود
(5,8.0,33,45)math.min